From 358e96f258e4373227e6853d679a4651ac80d9b6 Mon Sep 17 00:00:00 2001 From: yourh3ro Date: Mon, 16 Sep 2024 16:22:21 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=97#11=20=D0=A5=D1=80=D0=B0=D0=BD?= =?UTF-8?q?=D0=B8=D0=BB=D0=B8=D1=89=D0=B5=20=D1=81=D0=B5=D0=BA=D1=80=D0=B5?= =?UTF-8?q?=D1=82=D0=BE=D0=B2=20=D0=B4=D0=BB=D1=8F=20=D0=BF=D1=80=D0=B8?= =?UTF-8?q?=D0=BB=D0=BE=D0=B6=D0=B5=D0=BD=D0=B8=D1=8F.=20Vault.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + img/image17.png | Bin 0 -> 21962 bytes img/image18.png | Bin 0 -> 25540 bytes kubernetes-vault/README.md | 122 + kubernetes-vault/consul/.helmignore | 5 + kubernetes-vault/consul/Chart.yaml | 33 + kubernetes-vault/consul/README.md | 109 + kubernetes-vault/consul/addons/gen.sh | 37 + .../consul/addons/values/prometheus.yaml | 21 + kubernetes-vault/consul/assets/icon.png | Bin 0 -> 7981 bytes kubernetes-vault/consul/templates/NOTES.txt | 21 + .../consul/templates/_helpers.tpl | 704 +++ .../templates/auth-method-clusterrole.yaml | 18 + .../auth-method-clusterrolebinding.yaml | 39 + .../consul/templates/auth-method-secret.yaml | 16 + .../templates/auth-method-serviceaccount.yaml | 19 + .../templates/client-config-configmap.yaml | 40 + .../consul/templates/client-daemonset.yaml | 611 +++ .../templates/client-podsecuritypolicy.yaml | 76 + .../consul/templates/client-role.yaml | 43 + .../consul/templates/client-rolebinding.yaml | 20 + .../client-securitycontextconstraints.yaml | 61 + .../templates/client-serviceaccount.yaml | 23 + .../client-tmp-extra-config-configmap.yaml | 21 + .../consul/templates/cni-clusterrole.yaml | 38 + .../templates/cni-clusterrolebinding.yaml | 20 + .../consul/templates/cni-daemonset.yaml | 92 + .../cni-networkattachmentdefinition.yaml | 25 + .../templates/cni-podsecuritypolicy.yaml | 31 + .../consul/templates/cni-resourcequota.yaml | 22 + .../cni-securitycontextconstraints.yaml | 55 + .../consul/templates/cni-serviceaccount.yaml | 19 + .../templates/connect-inject-clusterrole.yaml | 291 ++ .../connect-inject-clusterrolebinding.yaml | 20 + .../templates/connect-inject-deployment.yaml | 371 ++ .../connect-inject-leader-election-role.yaml | 41 + ...ct-inject-leader-election-rolebinding.yaml | 21 + ...t-inject-mutatingwebhookconfiguration.yaml | 381 ++ .../connect-inject-podsecuritypolicy.yaml | 40 + .../templates/connect-inject-service.yaml | 23 + .../connect-inject-serviceaccount.yaml | 23 + ...inject-validatingwebhookconfiguration.yaml | 47 + .../connect-injector-disruptionbudget.yaml | 30 + .../consul/templates/crd-apigateways.yaml | 317 ++ .../crd-controlplanerequestlimits.yaml | 201 + .../templates/crd-exportedservices-v1.yaml | 147 + .../templates/crd-exportedservices.yaml | 114 + .../templates/crd-gatewayclassconfigs-v1.yaml | 232 + .../templates/crd-gatewayclassconfigs.yaml | 1729 +++++++ .../crd-gatewayclasses-external.yaml | 328 ++ .../consul/templates/crd-gatewayclasses.yaml | 130 + .../consul/templates/crd-gatewaypolicies.yaml | 302 ++ .../templates/crd-gateways-external.yaml | 882 ++++ .../templates/crd-grpcroutes-external.yaml | 766 +++ .../consul/templates/crd-grpcroutes.yaml | 669 +++ .../templates/crd-httproutes-external.yaml | 1914 +++++++ .../consul/templates/crd-httproutes.yaml | 726 +++ .../consul/templates/crd-ingressgateways.yaml | 466 ++ .../consul/templates/crd-jwtproviders.yaml | 375 ++ .../templates/crd-meshconfigurations.yaml | 107 + .../consul/templates/crd-meshes.yaml | 214 + .../consul/templates/crd-meshgateways.yaml | 140 + .../consul/templates/crd-meshservices.yaml | 61 + .../templates/crd-peeringacceptors.yaml | 152 + .../consul/templates/crd-peeringdialers.yaml | 152 + .../templates/crd-proxyconfigurations.yaml | 426 ++ .../consul/templates/crd-proxydefaults.yaml | 278 + .../crd-referencegrants-external.yaml | 208 + .../consul/templates/crd-registrations.yaml | 257 + .../templates/crd-routeauthfilters.yaml | 215 + .../templates/crd-routeretryfilters.yaml | 121 + .../templates/crd-routetimeoutfilters.yaml | 113 + .../consul/templates/crd-samenessgroups.yaml | 133 + .../consul/templates/crd-servicedefaults.yaml | 580 +++ .../templates/crd-serviceintentions.yaml | 310 ++ .../templates/crd-serviceresolvers.yaml | 372 ++ .../consul/templates/crd-servicerouters.yaml | 335 ++ .../templates/crd-servicesplitters.yaml | 194 + .../templates/crd-tcproutes-external.yaml | 281 + .../consul/templates/crd-tcproutes.yaml | 299 ++ .../templates/crd-terminatinggateways.yaml | 148 + .../templates/crd-tlsroutes-external.yaml | 291 ++ .../templates/crd-trafficpermissions.yaml | 280 + .../templates/crd-udproutes-external.yaml | 281 + .../create-federation-secret-job.yaml | 147 + ...e-federation-secret-podsecuritypolicy.yaml | 42 + .../create-federation-secret-role.yaml | 49 + .../create-federation-secret-rolebinding.yaml | 23 + ...eate-federation-secret-serviceaccount.yaml | 22 + .../consul/templates/datadog-agent-role.yaml | 38 + .../templates/datadog-agent-rolebinding.yaml | 26 + .../consul/templates/dns-service.yaml | 41 + .../templates/enterprise-license-job.yaml | 147 + .../enterprise-license-podsecuritypolicy.yaml | 39 + .../templates/enterprise-license-role.yaml | 37 + .../enterprise-license-rolebinding.yaml | 22 + .../enterprise-license-serviceaccount.yaml | 21 + .../templates/expose-servers-service.yaml | 63 + .../gateway-cleanup-clusterrole.yaml | 44 + .../gateway-cleanup-clusterrolebinding.yaml | 20 + .../consul/templates/gateway-cleanup-job.yaml | 68 + .../gateway-cleanup-podsecuritypolicy.yaml | 32 + .../gateway-cleanup-serviceaccount.yaml | 19 + .../gateway-resources-clusterrole.yaml | 47 + .../gateway-resources-clusterrolebinding.yaml | 20 + .../gateway-resources-configmap.yaml | 195 + .../templates/gateway-resources-job.yaml | 108 + .../gateway-resources-podsecuritypolicy.yaml | 32 + .../gateway-resources-serviceaccount.yaml | 19 + .../gossip-encryption-autogenerate-job.yaml | 71 + ...yption-autogenerate-podsecuritypolicy.yaml | 40 + .../gossip-encryption-autogenerate-role.yaml | 32 + ...p-encryption-autogenerate-rolebinding.yaml | 23 + ...ncryption-autogenerate-serviceaccount.yaml | 22 + .../ingress-gateways-deployment.yaml | 379 ++ .../ingress-gateways-podsecuritypolicy.yaml | 47 + .../templates/ingress-gateways-role.yaml | 46 + .../ingress-gateways-rolebinding.yaml | 25 + .../templates/ingress-gateways-service.yaml | 51 + .../ingress-gateways-serviceaccount.yaml | 35 + .../templates/mesh-gateway-clusterrole.yaml | 36 + .../mesh-gateway-clusterrolebinding.yaml | 22 + .../templates/mesh-gateway-deployment.yaml | 325 ++ .../mesh-gateway-podsecuritypolicy.yaml | 56 + .../templates/mesh-gateway-service.yaml | 35 + .../mesh-gateway-serviceaccount.yaml | 25 + .../consul/templates/partition-init-job.yaml | 132 + .../partition-init-podsecuritypolicy.yaml | 40 + .../consul/templates/partition-init-role.yaml | 35 + .../templates/partition-init-rolebinding.yaml | 24 + .../partition-init-serviceaccount.yaml | 23 + .../templates/partition-name-configmap.yaml | 19 + .../consul/templates/prometheus.yaml | 488 ++ .../server-acl-init-cleanup-job.yaml | 90 + ...er-acl-init-cleanup-podsecuritypolicy.yaml | 40 + .../server-acl-init-cleanup-role.yaml | 28 + .../server-acl-init-cleanup-rolebinding.yaml | 23 + ...erver-acl-init-cleanup-serviceaccount.yaml | 22 + .../consul/templates/server-acl-init-job.yaml | 350 ++ .../server-acl-init-podsecuritypolicy.yaml | 41 + .../templates/server-acl-init-role.yaml | 38 + .../server-acl-init-rolebinding.yaml | 23 + .../server-acl-init-serviceaccount.yaml | 22 + .../consul/templates/server-clusterrole.yaml | 16 + .../templates/server-clusterrolebinding.yaml | 18 + .../templates/server-config-configmap.yaml | 220 + .../templates/server-disruptionbudget.yaml | 26 + .../templates/server-podsecuritypolicy.yaml | 53 + .../consul/templates/server-role.yaml | 34 + .../consul/templates/server-rolebinding.yaml | 20 + .../server-securitycontextconstraints.yaml | 49 + .../consul/templates/server-service.yaml | 72 + .../templates/server-serviceaccount.yaml | 23 + .../server-snapshot-agent-configmap.yaml | 24 + .../consul/templates/server-statefulset.yaml | 757 +++ .../server-tmp-extra-config-configmap.yaml | 21 + .../templates/sync-catalog-clusterrole.yaml | 60 + .../sync-catalog-clusterrolebinding.yaml | 21 + .../templates/sync-catalog-deployment.yaml | 238 + .../sync-catalog-podsecuritypolicy.yaml | 40 + .../sync-catalog-serviceaccount.yaml | 24 + .../telemetry-collector-configmap.yaml | 18 + .../telemetry-collector-deployment.yaml | 453 ++ ...telemetry-collector-podsecuritypolicy.yaml | 42 + .../templates/telemetry-collector-role.yaml | 21 + .../telemetry-collector-rolebinding.yaml | 21 + .../telemetry-collector-service.yaml | 24 + .../telemetry-collector-serviceaccount.yaml | 23 + .../telemetry-collector-v2-deployment.yaml | 415 ++ .../terminating-gateways-deployment.yaml | 356 ++ ...erminating-gateways-podsecuritypolicy.yaml | 47 + .../templates/terminating-gateways-role.yaml | 32 + .../terminating-gateways-rolebinding.yaml | 26 + .../terminating-gateways-service.yaml | 31 + .../terminating-gateways-serviceaccount.yaml | 35 + .../consul/templates/tests/test-runner.yaml | 79 + .../templates/tls-init-cleanup-job.yaml | 85 + .../tls-init-cleanup-podsecuritypolicy.yaml | 43 + .../templates/tls-init-cleanup-role.yaml | 41 + .../tls-init-cleanup-rolebinding.yaml | 27 + .../tls-init-cleanup-serviceaccount.yaml | 26 + .../consul/templates/tls-init-job.yaml | 127 + .../templates/tls-init-podsecuritypolicy.yaml | 43 + .../consul/templates/tls-init-role.yaml | 38 + .../templates/tls-init-rolebinding.yaml | 27 + .../templates/tls-init-serviceaccount.yaml | 26 + .../consul/templates/ui-ingress.yaml | 85 + .../consul/templates/ui-service.yaml | 46 + .../webhook-cert-manager-clusterrole.yaml | 54 + ...bhook-cert-manager-clusterrolebinding.yaml | 21 + .../webhook-cert-manager-configmap.yaml | 29 + .../webhook-cert-manager-deployment.yaml | 79 + ...ebhook-cert-manager-podsecuritypolicy.yaml | 43 + .../webhook-cert-manager-serviceaccount.yaml | 20 + kubernetes-vault/consul/values.yaml | 3669 +++++++++++++ kubernetes-vault/external-secret.yaml | 39 + kubernetes-vault/external-secrets/Chart.lock | 6 + kubernetes-vault/external-secrets/Chart.yaml | 20 + kubernetes-vault/external-secrets/README.md | 225 + .../charts/bitwarden-sdk-server/.helmignore | 23 + .../charts/bitwarden-sdk-server/Chart.yaml | 6 + .../bitwarden-sdk-server/templates/NOTES.txt | 22 + .../templates/_helpers.tpl | 62 + .../templates/deployment.yaml | 77 + .../templates/service.yaml | 14 + .../templates/serviceaccount.yaml | 12 + .../__snapshot__/deployment_test.yaml.snap | 60 + .../tests/deployment_test.yaml | 9 + .../charts/bitwarden-sdk-server/values.yaml | 98 + .../external-secrets/templates/NOTES.txt | 7 + .../external-secrets/templates/_helpers.tpl | 198 + .../templates/cert-controller-deployment.yaml | 124 + .../cert-controller-poddisruptionbudget.yaml | 19 + .../templates/cert-controller-rbac.yaml | 86 + .../templates/cert-controller-service.yaml | 28 + .../cert-controller-serviceaccount.yaml | 16 + .../templates/crds/acraccesstoken.yaml | 203 + .../templates/crds/clusterexternalsecret.yaml | 666 +++ .../templates/crds/clustersecretstore.yaml | 4601 +++++++++++++++++ .../templates/crds/ecrauthorizationtoken.yaml | 177 + .../templates/crds/externalsecret.yaml | 820 +++ .../external-secrets/templates/crds/fake.yaml | 86 + .../templates/crds/gcraccesstoken.yaml | 138 + .../templates/crds/githubaccesstoken.yaml | 112 + .../templates/crds/password.yaml | 108 + .../templates/crds/pushsecret.yaml | 386 ++ .../templates/crds/secretstore.yaml | 4601 +++++++++++++++++ .../external-secrets/templates/crds/uuid.yaml | 72 + .../templates/crds/vaultdynamicsecret.yaml | 707 +++ .../templates/crds/webhook.yaml | 157 + .../templates/deployment.yaml | 146 + .../templates/extra-manifests.yaml | 4 + .../templates/poddisruptionbudget.yaml | 19 + .../external-secrets/templates/rbac.yaml | 301 ++ .../external-secrets/templates/service.yaml | 28 + .../templates/serviceaccount.yaml | 16 + .../templates/servicemonitor.yaml | 164 + .../templates/validatingwebhook.yaml | 78 + .../templates/webhook-certificate.yaml | 30 + .../templates/webhook-deployment.yaml | 128 + .../webhook-poddisruptionbudget.yaml | 20 + .../templates/webhook-secret.yaml | 14 + .../templates/webhook-service.yaml | 37 + .../templates/webhook-serviceaccount.yaml | 16 + .../external-secrets/values.schema.json | 905 ++++ kubernetes-vault/external-secrets/values.yaml | 532 ++ kubernetes-vault/otus-policy.hcl | 3 + kubernetes-vault/vault-auth-sa.yaml | 18 + kubernetes-vault/vault/.helmignore | 28 + kubernetes-vault/vault/CHANGELOG.md | 560 ++ kubernetes-vault/vault/CODEOWNERS | 1 + kubernetes-vault/vault/CONTRIBUTING.md | 247 + kubernetes-vault/vault/Chart.yaml | 23 + kubernetes-vault/vault/LICENSE | 355 ++ kubernetes-vault/vault/Makefile | 101 + kubernetes-vault/vault/README.md | 43 + kubernetes-vault/vault/templates/NOTES.txt | 14 + kubernetes-vault/vault/templates/_helpers.tpl | 1105 ++++ .../vault/templates/csi-agent-configmap.yaml | 34 + .../vault/templates/csi-clusterrole.yaml | 23 + .../templates/csi-clusterrolebinding.yaml | 24 + .../vault/templates/csi-daemonset.yaml | 157 + .../vault/templates/csi-role.yaml | 32 + .../vault/templates/csi-rolebinding.yaml | 25 + .../vault/templates/csi-serviceaccount.yaml | 21 + .../templates/injector-certs-secret.yaml | 19 + .../vault/templates/injector-clusterrole.yaml | 30 + .../injector-clusterrolebinding.yaml | 24 + .../vault/templates/injector-deployment.yaml | 179 + .../templates/injector-disruptionbudget.yaml | 25 + .../templates/injector-mutating-webhook.yaml | 45 + .../templates/injector-network-policy.yaml | 29 + .../vault/templates/injector-psp-role.yaml | 25 + .../templates/injector-psp-rolebinding.yaml | 26 + .../vault/templates/injector-psp.yaml | 51 + .../vault/templates/injector-role.yaml | 34 + .../vault/templates/injector-rolebinding.yaml | 27 + .../vault/templates/injector-service.yaml | 27 + .../templates/injector-serviceaccount.yaml | 18 + .../templates/prometheus-prometheusrules.yaml | 31 + .../templates/prometheus-servicemonitor.yaml | 58 + .../templates/server-clusterrolebinding.yaml | 29 + .../templates/server-config-configmap.yaml | 31 + .../templates/server-discovery-role.yaml | 26 + .../server-discovery-rolebinding.yaml | 34 + .../templates/server-disruptionbudget.yaml | 31 + .../templates/server-ha-active-service.yaml | 64 + .../templates/server-ha-standby-service.yaml | 63 + .../templates/server-headless-service.yaml | 47 + .../vault/templates/server-ingress.yaml | 69 + .../templates/server-network-policy.yaml | 24 + .../vault/templates/server-psp-role.yaml | 25 + .../templates/server-psp-rolebinding.yaml | 26 + .../vault/templates/server-psp.yaml | 54 + .../vault/templates/server-route.yaml | 39 + .../vault/templates/server-service.yaml | 59 + .../server-serviceaccount-secret.yaml | 21 + .../templates/server-serviceaccount.yaml | 22 + .../vault/templates/server-statefulset.yaml | 232 + .../vault/templates/tests/server-test.yaml | 56 + .../vault/templates/ui-service.yaml | 50 + kubernetes-vault/vault/values.openshift.yaml | 24 + kubernetes-vault/vault/values.schema.json | 1309 +++++ kubernetes-vault/vault/values.yaml | 1335 +++++ 304 files changed, 54328 insertions(+) create mode 100644 img/image17.png create mode 100644 img/image18.png create mode 100644 kubernetes-vault/README.md create mode 100644 kubernetes-vault/consul/.helmignore create mode 100644 kubernetes-vault/consul/Chart.yaml create mode 100644 kubernetes-vault/consul/README.md create mode 100644 kubernetes-vault/consul/addons/gen.sh create mode 100644 kubernetes-vault/consul/addons/values/prometheus.yaml create mode 100644 kubernetes-vault/consul/assets/icon.png create mode 100644 kubernetes-vault/consul/templates/NOTES.txt create mode 100644 kubernetes-vault/consul/templates/_helpers.tpl create mode 100644 kubernetes-vault/consul/templates/auth-method-clusterrole.yaml create mode 100644 kubernetes-vault/consul/templates/auth-method-clusterrolebinding.yaml create mode 100644 kubernetes-vault/consul/templates/auth-method-secret.yaml create mode 100644 kubernetes-vault/consul/templates/auth-method-serviceaccount.yaml create mode 100644 kubernetes-vault/consul/templates/client-config-configmap.yaml create mode 100644 kubernetes-vault/consul/templates/client-daemonset.yaml create mode 100644 kubernetes-vault/consul/templates/client-podsecuritypolicy.yaml create mode 100644 kubernetes-vault/consul/templates/client-role.yaml create mode 100644 kubernetes-vault/consul/templates/client-rolebinding.yaml create mode 100644 kubernetes-vault/consul/templates/client-securitycontextconstraints.yaml create mode 100644 kubernetes-vault/consul/templates/client-serviceaccount.yaml create mode 100644 kubernetes-vault/consul/templates/client-tmp-extra-config-configmap.yaml create mode 100644 kubernetes-vault/consul/templates/cni-clusterrole.yaml create mode 100644 kubernetes-vault/consul/templates/cni-clusterrolebinding.yaml create mode 100644 kubernetes-vault/consul/templates/cni-daemonset.yaml create mode 100644 kubernetes-vault/consul/templates/cni-networkattachmentdefinition.yaml create mode 100644 kubernetes-vault/consul/templates/cni-podsecuritypolicy.yaml create mode 100644 kubernetes-vault/consul/templates/cni-resourcequota.yaml create mode 100644 kubernetes-vault/consul/templates/cni-securitycontextconstraints.yaml create mode 100644 kubernetes-vault/consul/templates/cni-serviceaccount.yaml create mode 100644 kubernetes-vault/consul/templates/connect-inject-clusterrole.yaml create mode 100644 kubernetes-vault/consul/templates/connect-inject-clusterrolebinding.yaml create mode 100644 kubernetes-vault/consul/templates/connect-inject-deployment.yaml create mode 100644 kubernetes-vault/consul/templates/connect-inject-leader-election-role.yaml create mode 100644 kubernetes-vault/consul/templates/connect-inject-leader-election-rolebinding.yaml create mode 100644 kubernetes-vault/consul/templates/connect-inject-mutatingwebhookconfiguration.yaml create mode 100644 kubernetes-vault/consul/templates/connect-inject-podsecuritypolicy.yaml create mode 100644 kubernetes-vault/consul/templates/connect-inject-service.yaml create mode 100644 kubernetes-vault/consul/templates/connect-inject-serviceaccount.yaml create mode 100644 kubernetes-vault/consul/templates/connect-inject-validatingwebhookconfiguration.yaml create mode 100644 kubernetes-vault/consul/templates/connect-injector-disruptionbudget.yaml create mode 100644 kubernetes-vault/consul/templates/crd-apigateways.yaml create mode 100644 kubernetes-vault/consul/templates/crd-controlplanerequestlimits.yaml create mode 100644 kubernetes-vault/consul/templates/crd-exportedservices-v1.yaml create mode 100644 kubernetes-vault/consul/templates/crd-exportedservices.yaml create mode 100644 kubernetes-vault/consul/templates/crd-gatewayclassconfigs-v1.yaml create mode 100644 kubernetes-vault/consul/templates/crd-gatewayclassconfigs.yaml create mode 100644 kubernetes-vault/consul/templates/crd-gatewayclasses-external.yaml create mode 100644 kubernetes-vault/consul/templates/crd-gatewayclasses.yaml create mode 100644 kubernetes-vault/consul/templates/crd-gatewaypolicies.yaml create mode 100644 kubernetes-vault/consul/templates/crd-gateways-external.yaml create mode 100644 kubernetes-vault/consul/templates/crd-grpcroutes-external.yaml create mode 100644 kubernetes-vault/consul/templates/crd-grpcroutes.yaml create mode 100644 kubernetes-vault/consul/templates/crd-httproutes-external.yaml create mode 100644 kubernetes-vault/consul/templates/crd-httproutes.yaml create mode 100644 kubernetes-vault/consul/templates/crd-ingressgateways.yaml create mode 100644 kubernetes-vault/consul/templates/crd-jwtproviders.yaml create mode 100644 kubernetes-vault/consul/templates/crd-meshconfigurations.yaml create mode 100644 kubernetes-vault/consul/templates/crd-meshes.yaml create mode 100644 kubernetes-vault/consul/templates/crd-meshgateways.yaml create mode 100644 kubernetes-vault/consul/templates/crd-meshservices.yaml create mode 100644 kubernetes-vault/consul/templates/crd-peeringacceptors.yaml create mode 100644 kubernetes-vault/consul/templates/crd-peeringdialers.yaml create mode 100644 kubernetes-vault/consul/templates/crd-proxyconfigurations.yaml create mode 100644 kubernetes-vault/consul/templates/crd-proxydefaults.yaml create mode 100644 kubernetes-vault/consul/templates/crd-referencegrants-external.yaml create mode 100644 kubernetes-vault/consul/templates/crd-registrations.yaml create mode 100644 kubernetes-vault/consul/templates/crd-routeauthfilters.yaml create mode 100644 kubernetes-vault/consul/templates/crd-routeretryfilters.yaml create mode 100644 kubernetes-vault/consul/templates/crd-routetimeoutfilters.yaml create mode 100644 kubernetes-vault/consul/templates/crd-samenessgroups.yaml create mode 100644 kubernetes-vault/consul/templates/crd-servicedefaults.yaml create mode 100644 kubernetes-vault/consul/templates/crd-serviceintentions.yaml create mode 100644 kubernetes-vault/consul/templates/crd-serviceresolvers.yaml create mode 100644 kubernetes-vault/consul/templates/crd-servicerouters.yaml create mode 100644 kubernetes-vault/consul/templates/crd-servicesplitters.yaml create mode 100644 kubernetes-vault/consul/templates/crd-tcproutes-external.yaml create mode 100644 kubernetes-vault/consul/templates/crd-tcproutes.yaml create mode 100644 kubernetes-vault/consul/templates/crd-terminatinggateways.yaml create mode 100644 kubernetes-vault/consul/templates/crd-tlsroutes-external.yaml create mode 100644 kubernetes-vault/consul/templates/crd-trafficpermissions.yaml create mode 100644 kubernetes-vault/consul/templates/crd-udproutes-external.yaml create mode 100644 kubernetes-vault/consul/templates/create-federation-secret-job.yaml create mode 100644 kubernetes-vault/consul/templates/create-federation-secret-podsecuritypolicy.yaml create mode 100644 kubernetes-vault/consul/templates/create-federation-secret-role.yaml create mode 100644 kubernetes-vault/consul/templates/create-federation-secret-rolebinding.yaml create mode 100644 kubernetes-vault/consul/templates/create-federation-secret-serviceaccount.yaml create mode 100644 kubernetes-vault/consul/templates/datadog-agent-role.yaml create mode 100644 kubernetes-vault/consul/templates/datadog-agent-rolebinding.yaml create mode 100644 kubernetes-vault/consul/templates/dns-service.yaml create mode 100644 kubernetes-vault/consul/templates/enterprise-license-job.yaml create mode 100644 kubernetes-vault/consul/templates/enterprise-license-podsecuritypolicy.yaml create mode 100644 kubernetes-vault/consul/templates/enterprise-license-role.yaml create mode 100644 kubernetes-vault/consul/templates/enterprise-license-rolebinding.yaml create mode 100644 kubernetes-vault/consul/templates/enterprise-license-serviceaccount.yaml create mode 100644 kubernetes-vault/consul/templates/expose-servers-service.yaml create mode 100644 kubernetes-vault/consul/templates/gateway-cleanup-clusterrole.yaml create mode 100644 kubernetes-vault/consul/templates/gateway-cleanup-clusterrolebinding.yaml create mode 100644 kubernetes-vault/consul/templates/gateway-cleanup-job.yaml create mode 100644 kubernetes-vault/consul/templates/gateway-cleanup-podsecuritypolicy.yaml create mode 100644 kubernetes-vault/consul/templates/gateway-cleanup-serviceaccount.yaml create mode 100644 kubernetes-vault/consul/templates/gateway-resources-clusterrole.yaml create mode 100644 kubernetes-vault/consul/templates/gateway-resources-clusterrolebinding.yaml create mode 100644 kubernetes-vault/consul/templates/gateway-resources-configmap.yaml create mode 100644 kubernetes-vault/consul/templates/gateway-resources-job.yaml create mode 100644 kubernetes-vault/consul/templates/gateway-resources-podsecuritypolicy.yaml create mode 100644 kubernetes-vault/consul/templates/gateway-resources-serviceaccount.yaml create mode 100644 kubernetes-vault/consul/templates/gossip-encryption-autogenerate-job.yaml create mode 100644 kubernetes-vault/consul/templates/gossip-encryption-autogenerate-podsecuritypolicy.yaml create mode 100644 kubernetes-vault/consul/templates/gossip-encryption-autogenerate-role.yaml create mode 100644 kubernetes-vault/consul/templates/gossip-encryption-autogenerate-rolebinding.yaml create mode 100644 kubernetes-vault/consul/templates/gossip-encryption-autogenerate-serviceaccount.yaml create mode 100644 kubernetes-vault/consul/templates/ingress-gateways-deployment.yaml create mode 100644 kubernetes-vault/consul/templates/ingress-gateways-podsecuritypolicy.yaml create mode 100644 kubernetes-vault/consul/templates/ingress-gateways-role.yaml create mode 100644 kubernetes-vault/consul/templates/ingress-gateways-rolebinding.yaml create mode 100644 kubernetes-vault/consul/templates/ingress-gateways-service.yaml create mode 100644 kubernetes-vault/consul/templates/ingress-gateways-serviceaccount.yaml create mode 100644 kubernetes-vault/consul/templates/mesh-gateway-clusterrole.yaml create mode 100644 kubernetes-vault/consul/templates/mesh-gateway-clusterrolebinding.yaml create mode 100644 kubernetes-vault/consul/templates/mesh-gateway-deployment.yaml create mode 100644 kubernetes-vault/consul/templates/mesh-gateway-podsecuritypolicy.yaml create mode 100644 kubernetes-vault/consul/templates/mesh-gateway-service.yaml create mode 100644 kubernetes-vault/consul/templates/mesh-gateway-serviceaccount.yaml create mode 100644 kubernetes-vault/consul/templates/partition-init-job.yaml create mode 100644 kubernetes-vault/consul/templates/partition-init-podsecuritypolicy.yaml create mode 100644 kubernetes-vault/consul/templates/partition-init-role.yaml create mode 100644 kubernetes-vault/consul/templates/partition-init-rolebinding.yaml create mode 100644 kubernetes-vault/consul/templates/partition-init-serviceaccount.yaml create mode 100644 kubernetes-vault/consul/templates/partition-name-configmap.yaml create mode 100644 kubernetes-vault/consul/templates/prometheus.yaml create mode 100644 kubernetes-vault/consul/templates/server-acl-init-cleanup-job.yaml create mode 100644 kubernetes-vault/consul/templates/server-acl-init-cleanup-podsecuritypolicy.yaml create mode 100644 kubernetes-vault/consul/templates/server-acl-init-cleanup-role.yaml create mode 100644 kubernetes-vault/consul/templates/server-acl-init-cleanup-rolebinding.yaml create mode 100644 kubernetes-vault/consul/templates/server-acl-init-cleanup-serviceaccount.yaml create mode 100644 kubernetes-vault/consul/templates/server-acl-init-job.yaml create mode 100644 kubernetes-vault/consul/templates/server-acl-init-podsecuritypolicy.yaml create mode 100644 kubernetes-vault/consul/templates/server-acl-init-role.yaml create mode 100644 kubernetes-vault/consul/templates/server-acl-init-rolebinding.yaml create mode 100644 kubernetes-vault/consul/templates/server-acl-init-serviceaccount.yaml create mode 100644 kubernetes-vault/consul/templates/server-clusterrole.yaml create mode 100644 kubernetes-vault/consul/templates/server-clusterrolebinding.yaml create mode 100644 kubernetes-vault/consul/templates/server-config-configmap.yaml create mode 100644 kubernetes-vault/consul/templates/server-disruptionbudget.yaml create mode 100644 kubernetes-vault/consul/templates/server-podsecuritypolicy.yaml create mode 100644 kubernetes-vault/consul/templates/server-role.yaml create mode 100644 kubernetes-vault/consul/templates/server-rolebinding.yaml create mode 100644 kubernetes-vault/consul/templates/server-securitycontextconstraints.yaml create mode 100644 kubernetes-vault/consul/templates/server-service.yaml create mode 100644 kubernetes-vault/consul/templates/server-serviceaccount.yaml create mode 100644 kubernetes-vault/consul/templates/server-snapshot-agent-configmap.yaml create mode 100644 kubernetes-vault/consul/templates/server-statefulset.yaml create mode 100644 kubernetes-vault/consul/templates/server-tmp-extra-config-configmap.yaml create mode 100644 kubernetes-vault/consul/templates/sync-catalog-clusterrole.yaml create mode 100644 kubernetes-vault/consul/templates/sync-catalog-clusterrolebinding.yaml create mode 100644 kubernetes-vault/consul/templates/sync-catalog-deployment.yaml create mode 100644 kubernetes-vault/consul/templates/sync-catalog-podsecuritypolicy.yaml create mode 100644 kubernetes-vault/consul/templates/sync-catalog-serviceaccount.yaml create mode 100644 kubernetes-vault/consul/templates/telemetry-collector-configmap.yaml create mode 100644 kubernetes-vault/consul/templates/telemetry-collector-deployment.yaml create mode 100644 kubernetes-vault/consul/templates/telemetry-collector-podsecuritypolicy.yaml create mode 100644 kubernetes-vault/consul/templates/telemetry-collector-role.yaml create mode 100644 kubernetes-vault/consul/templates/telemetry-collector-rolebinding.yaml create mode 100644 kubernetes-vault/consul/templates/telemetry-collector-service.yaml create mode 100644 kubernetes-vault/consul/templates/telemetry-collector-serviceaccount.yaml create mode 100644 kubernetes-vault/consul/templates/telemetry-collector-v2-deployment.yaml create mode 100644 kubernetes-vault/consul/templates/terminating-gateways-deployment.yaml create mode 100644 kubernetes-vault/consul/templates/terminating-gateways-podsecuritypolicy.yaml create mode 100644 kubernetes-vault/consul/templates/terminating-gateways-role.yaml create mode 100644 kubernetes-vault/consul/templates/terminating-gateways-rolebinding.yaml create mode 100644 kubernetes-vault/consul/templates/terminating-gateways-service.yaml create mode 100644 kubernetes-vault/consul/templates/terminating-gateways-serviceaccount.yaml create mode 100644 kubernetes-vault/consul/templates/tests/test-runner.yaml create mode 100644 kubernetes-vault/consul/templates/tls-init-cleanup-job.yaml create mode 100644 kubernetes-vault/consul/templates/tls-init-cleanup-podsecuritypolicy.yaml create mode 100644 kubernetes-vault/consul/templates/tls-init-cleanup-role.yaml create mode 100644 kubernetes-vault/consul/templates/tls-init-cleanup-rolebinding.yaml create mode 100644 kubernetes-vault/consul/templates/tls-init-cleanup-serviceaccount.yaml create mode 100644 kubernetes-vault/consul/templates/tls-init-job.yaml create mode 100644 kubernetes-vault/consul/templates/tls-init-podsecuritypolicy.yaml create mode 100644 kubernetes-vault/consul/templates/tls-init-role.yaml create mode 100644 kubernetes-vault/consul/templates/tls-init-rolebinding.yaml create mode 100644 kubernetes-vault/consul/templates/tls-init-serviceaccount.yaml create mode 100644 kubernetes-vault/consul/templates/ui-ingress.yaml create mode 100644 kubernetes-vault/consul/templates/ui-service.yaml create mode 100644 kubernetes-vault/consul/templates/webhook-cert-manager-clusterrole.yaml create mode 100644 kubernetes-vault/consul/templates/webhook-cert-manager-clusterrolebinding.yaml create mode 100644 kubernetes-vault/consul/templates/webhook-cert-manager-configmap.yaml create mode 100644 kubernetes-vault/consul/templates/webhook-cert-manager-deployment.yaml create mode 100644 kubernetes-vault/consul/templates/webhook-cert-manager-podsecuritypolicy.yaml create mode 100644 kubernetes-vault/consul/templates/webhook-cert-manager-serviceaccount.yaml create mode 100644 kubernetes-vault/consul/values.yaml create mode 100644 kubernetes-vault/external-secret.yaml create mode 100644 kubernetes-vault/external-secrets/Chart.lock create mode 100644 kubernetes-vault/external-secrets/Chart.yaml create mode 100644 kubernetes-vault/external-secrets/README.md create mode 100644 kubernetes-vault/external-secrets/charts/bitwarden-sdk-server/.helmignore create mode 100644 kubernetes-vault/external-secrets/charts/bitwarden-sdk-server/Chart.yaml create mode 100644 kubernetes-vault/external-secrets/charts/bitwarden-sdk-server/templates/NOTES.txt create mode 100644 kubernetes-vault/external-secrets/charts/bitwarden-sdk-server/templates/_helpers.tpl create mode 100644 kubernetes-vault/external-secrets/charts/bitwarden-sdk-server/templates/deployment.yaml create mode 100644 kubernetes-vault/external-secrets/charts/bitwarden-sdk-server/templates/service.yaml create mode 100644 kubernetes-vault/external-secrets/charts/bitwarden-sdk-server/templates/serviceaccount.yaml create mode 100644 kubernetes-vault/external-secrets/charts/bitwarden-sdk-server/tests/__snapshot__/deployment_test.yaml.snap create mode 100644 kubernetes-vault/external-secrets/charts/bitwarden-sdk-server/tests/deployment_test.yaml create mode 100644 kubernetes-vault/external-secrets/charts/bitwarden-sdk-server/values.yaml create mode 100644 kubernetes-vault/external-secrets/templates/NOTES.txt create mode 100644 kubernetes-vault/external-secrets/templates/_helpers.tpl create mode 100644 kubernetes-vault/external-secrets/templates/cert-controller-deployment.yaml create mode 100644 kubernetes-vault/external-secrets/templates/cert-controller-poddisruptionbudget.yaml create mode 100644 kubernetes-vault/external-secrets/templates/cert-controller-rbac.yaml create mode 100644 kubernetes-vault/external-secrets/templates/cert-controller-service.yaml create mode 100644 kubernetes-vault/external-secrets/templates/cert-controller-serviceaccount.yaml create mode 100644 kubernetes-vault/external-secrets/templates/crds/acraccesstoken.yaml create mode 100644 kubernetes-vault/external-secrets/templates/crds/clusterexternalsecret.yaml create mode 100644 kubernetes-vault/external-secrets/templates/crds/clustersecretstore.yaml create mode 100644 kubernetes-vault/external-secrets/templates/crds/ecrauthorizationtoken.yaml create mode 100644 kubernetes-vault/external-secrets/templates/crds/externalsecret.yaml create mode 100644 kubernetes-vault/external-secrets/templates/crds/fake.yaml create mode 100644 kubernetes-vault/external-secrets/templates/crds/gcraccesstoken.yaml create mode 100644 kubernetes-vault/external-secrets/templates/crds/githubaccesstoken.yaml create mode 100644 kubernetes-vault/external-secrets/templates/crds/password.yaml create mode 100644 kubernetes-vault/external-secrets/templates/crds/pushsecret.yaml create mode 100644 kubernetes-vault/external-secrets/templates/crds/secretstore.yaml create mode 100644 kubernetes-vault/external-secrets/templates/crds/uuid.yaml create mode 100644 kubernetes-vault/external-secrets/templates/crds/vaultdynamicsecret.yaml create mode 100644 kubernetes-vault/external-secrets/templates/crds/webhook.yaml create mode 100644 kubernetes-vault/external-secrets/templates/deployment.yaml create mode 100644 kubernetes-vault/external-secrets/templates/extra-manifests.yaml create mode 100644 kubernetes-vault/external-secrets/templates/poddisruptionbudget.yaml create mode 100644 kubernetes-vault/external-secrets/templates/rbac.yaml create mode 100644 kubernetes-vault/external-secrets/templates/service.yaml create mode 100644 kubernetes-vault/external-secrets/templates/serviceaccount.yaml create mode 100644 kubernetes-vault/external-secrets/templates/servicemonitor.yaml create mode 100644 kubernetes-vault/external-secrets/templates/validatingwebhook.yaml create mode 100644 kubernetes-vault/external-secrets/templates/webhook-certificate.yaml create mode 100644 kubernetes-vault/external-secrets/templates/webhook-deployment.yaml create mode 100644 kubernetes-vault/external-secrets/templates/webhook-poddisruptionbudget.yaml create mode 100644 kubernetes-vault/external-secrets/templates/webhook-secret.yaml create mode 100644 kubernetes-vault/external-secrets/templates/webhook-service.yaml create mode 100644 kubernetes-vault/external-secrets/templates/webhook-serviceaccount.yaml create mode 100644 kubernetes-vault/external-secrets/values.schema.json create mode 100644 kubernetes-vault/external-secrets/values.yaml create mode 100644 kubernetes-vault/otus-policy.hcl create mode 100644 kubernetes-vault/vault-auth-sa.yaml create mode 100644 kubernetes-vault/vault/.helmignore create mode 100644 kubernetes-vault/vault/CHANGELOG.md create mode 100644 kubernetes-vault/vault/CODEOWNERS create mode 100644 kubernetes-vault/vault/CONTRIBUTING.md create mode 100644 kubernetes-vault/vault/Chart.yaml create mode 100644 kubernetes-vault/vault/LICENSE create mode 100644 kubernetes-vault/vault/Makefile create mode 100644 kubernetes-vault/vault/README.md create mode 100644 kubernetes-vault/vault/templates/NOTES.txt create mode 100644 kubernetes-vault/vault/templates/_helpers.tpl create mode 100644 kubernetes-vault/vault/templates/csi-agent-configmap.yaml create mode 100644 kubernetes-vault/vault/templates/csi-clusterrole.yaml create mode 100644 kubernetes-vault/vault/templates/csi-clusterrolebinding.yaml create mode 100644 kubernetes-vault/vault/templates/csi-daemonset.yaml create mode 100644 kubernetes-vault/vault/templates/csi-role.yaml create mode 100644 kubernetes-vault/vault/templates/csi-rolebinding.yaml create mode 100644 kubernetes-vault/vault/templates/csi-serviceaccount.yaml create mode 100644 kubernetes-vault/vault/templates/injector-certs-secret.yaml create mode 100644 kubernetes-vault/vault/templates/injector-clusterrole.yaml create mode 100644 kubernetes-vault/vault/templates/injector-clusterrolebinding.yaml create mode 100644 kubernetes-vault/vault/templates/injector-deployment.yaml create mode 100644 kubernetes-vault/vault/templates/injector-disruptionbudget.yaml create mode 100644 kubernetes-vault/vault/templates/injector-mutating-webhook.yaml create mode 100644 kubernetes-vault/vault/templates/injector-network-policy.yaml create mode 100644 kubernetes-vault/vault/templates/injector-psp-role.yaml create mode 100644 kubernetes-vault/vault/templates/injector-psp-rolebinding.yaml create mode 100644 kubernetes-vault/vault/templates/injector-psp.yaml create mode 100644 kubernetes-vault/vault/templates/injector-role.yaml create mode 100644 kubernetes-vault/vault/templates/injector-rolebinding.yaml create mode 100644 kubernetes-vault/vault/templates/injector-service.yaml create mode 100644 kubernetes-vault/vault/templates/injector-serviceaccount.yaml create mode 100644 kubernetes-vault/vault/templates/prometheus-prometheusrules.yaml create mode 100644 kubernetes-vault/vault/templates/prometheus-servicemonitor.yaml create mode 100644 kubernetes-vault/vault/templates/server-clusterrolebinding.yaml create mode 100644 kubernetes-vault/vault/templates/server-config-configmap.yaml create mode 100644 kubernetes-vault/vault/templates/server-discovery-role.yaml create mode 100644 kubernetes-vault/vault/templates/server-discovery-rolebinding.yaml create mode 100644 kubernetes-vault/vault/templates/server-disruptionbudget.yaml create mode 100644 kubernetes-vault/vault/templates/server-ha-active-service.yaml create mode 100644 kubernetes-vault/vault/templates/server-ha-standby-service.yaml create mode 100644 kubernetes-vault/vault/templates/server-headless-service.yaml create mode 100644 kubernetes-vault/vault/templates/server-ingress.yaml create mode 100644 kubernetes-vault/vault/templates/server-network-policy.yaml create mode 100644 kubernetes-vault/vault/templates/server-psp-role.yaml create mode 100644 kubernetes-vault/vault/templates/server-psp-rolebinding.yaml create mode 100644 kubernetes-vault/vault/templates/server-psp.yaml create mode 100644 kubernetes-vault/vault/templates/server-route.yaml create mode 100644 kubernetes-vault/vault/templates/server-service.yaml create mode 100644 kubernetes-vault/vault/templates/server-serviceaccount-secret.yaml create mode 100644 kubernetes-vault/vault/templates/server-serviceaccount.yaml create mode 100644 kubernetes-vault/vault/templates/server-statefulset.yaml create mode 100644 kubernetes-vault/vault/templates/tests/server-test.yaml create mode 100644 kubernetes-vault/vault/templates/ui-service.yaml create mode 100644 kubernetes-vault/vault/values.openshift.yaml create mode 100644 kubernetes-vault/vault/values.schema.json create mode 100644 kubernetes-vault/vault/values.yaml diff --git a/README.md b/README.md index 2162975..b70f9e1 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ [ДЗ#8 Мониторинг приложения в кластере](kubernetes-monitoring/README.md) [ДЗ#9 Сервисы централизованного логирования для Kubernetes](kubernetes-logging/README.md) [ДЗ#10 GitOps и инструменты поставки](kubernetes-gitops/README.md) +[ДЗ#11 Хранилище секретов для приложения. Vault.](kubernetes-vault/README.md) ## Tricks, Tools, Hints ### k9s diff --git a/img/image17.png b/img/image17.png new file mode 100644 index 0000000000000000000000000000000000000000..810e6e303df941d3df7baf8878cf8a1cd26b391d GIT binary patch literal 21962 zcmd43cU)6zmo}`&qdrGe4o3u}9;HY}q<0koLzP|?ckYtXWs9bcb=K|`_1qB1H#_9_r2G??^UjKt+k1{Ypi$f z4ELF1$Bvx?-MMXc?AWjR$BzA?^S4vLnV$E5umT^);bwZbj#c;bE&~U@y4*CndF)ti zBFn-3lfdzBkM7vQj~zSziTQIJ>+|Npv167FpxZYsf}m@J-}3E;&{{uc`Yh@)uY<&0 zF`+ta!*_@8-b%5GX)l2qeC39kN`*(4FZ;YHPjzQ=t5~l1F82EGqc+;F{&vgZB%6+i zwq4!lA2XzEe_tFLl>s*)qo`Z=iK`7eZ9eeO9lV`~(igE`0XdEhh(-PaeE0=D{R8-T zY^zt|0X^tJce)Bir_YD!z3ld9P zG0@0U1J2ez&pa*cRHH7|9&F*Y8fPVb0vLO~<}4#D2ywuqs_uC(enVg&qNk}5!Xh!Lzo~n# zn6lL{axf*33#W@$^r^X9df z_LR{JY+%m@kYR4JouMJ3woq_Kt-yVJI(`eiGcMQoc`L~WtA|mW|!cvW3AXGx0Y`sSgDkr^SqW z>$dEEL;%9)Hw@FOlr#e4hqiWw#IEgO=1}d|b~ekOK+UZ)KtqnchKNYRWq!2yckD;? z0RK5n{bx-aG*>axJ4D#+PMO8(CS_=BBzj22%09FY0+mOH1mfVfXVmra&FSu8Wb><< z{50>kP-&?zeXrEP9nU6BtvubuPyAEC7CFZ4Jw_Q!$zavLMuRmQ1Ts0V(i;PWuLoy-Uo0N_jT%F=n@U$I-J8Zvnbe-B8?U=1vSuPsBE)*rC6;Gi< z%NRqy*d+^XO)?!_eJ)_7P0;b}C+(_24S<*hsPa>0cw^N5QC3!+UdOzH#k!p%= zURc3IE<7UlymOt7cJsl-T3R`@;a5uFB+A%`rIf30U}4pw+}}KKilHPU3MFO69e!WzY}v4N$9M@| z^E6hm&_||&@=%|mFuF9A)mFR6BD=cY5r5M(g49>*6RyNP8Dbdk!GITXZN7k1R3hjbeY1aV=l89j4Upnh5cREj-?rowWTJE zwCobk>8=uiK8j>&lSo2Bt51iRuEy9Zy}H?Id%dZh#saMDxbHdrhw56_`xzhhWPK0f zAaaq^mfMfl#* z)?wft%zyy1xz?qE@mZk2+=~vh#5xW!p)v!LbBTmTnqk-m35&J;LH0&gBjhRaQlbMd_K^BHJ-t_0fFPdG_9L@-Emv>$mENWwE(bQ* zpp|IOIxTM1TQL%!;iDJ;vpxSXj-QRlC|3P-iQ}*%g7z%v8~_Nz|Y&rG_KF671FXAD@Z;v@2= zH3Pv83LXB(K z+(crOn}q2ortQ8SZq(_ngvqWbSzZR+AM#;^#=U$H0Y$V%UK35|*ni^tasyfiyDBon z=Mo-Xqa3vKqgms{@7-~3xXvZ8Ov2phwTs#j3hOrfH8UY*fF5bjJ-v^|5E$0Kfsjp( zv!9xYYz?neH1gaQ_YG^Q6VHffv-3Ex-w(8MY}%q;Y2f0qr>%u4+dBJ!N| z(jS~fFN-Yb`4;xI7DOhl-7=lbpWhpRQK#NsUKTiUS~7s=MR3@UZVxHl$(7bz{eXJ9_|{q z+snejYS_h^SQCCY%VmG@(H9TLxP$dM$K72>WxD$H1jfYID9F%LqZWF3b7l9Rik7L1 zQ-C!0j=OUww^0WF?z%s-tAv;~$V=*6Qd{?KoQb`(@m}Ud*Bbm&hIj3!z?y_fvJC6P z5QY&a=E>n^fg@ouG9+BxobOLR5?|k| z&kw~iQ)_2ZLEIE@QN&)3`bc6YxhPIf9<4sqfx<#385%{JgOqfXU5>?B>lV%8X;wve5q z*RWwcYr@S?&kNemEo-QThIaRqUZzSVZGm6*dtlCE?fIJQLrr;6b9P(58IluN&TEM2 z8uu@JWSP^`ORAuC-!$qMGtxVhmXXZhszF0@L%(mdX4aFJ1Ae@&^{Ii_oF%kF&c}%Y9mInT*RkC!Z)&l4MWhidmq3i z@zI4l`-ZCuu6NFA_ynD05Y}Y(8JXt|TjW!B4md{24+EmLrQ4*)9dnt@OId22c9w+a z`qQC*_V2qnQ8SuKrOD|M0Fc=7Y9cp12(Q?ggpoL&o#;d+i}JJl2;_1fZ9jY*!~LdAbOnB6#LF3YEIe_EvCP`8iv8()%Cn zFtLF3YFV&ywHTa5&krjp$MOf>leTE%^HB&E zG%c($Zm-3_%W{E8TQjxV(3xlqL4E*p5FB%Ofcr|`j>n2F3()vSD}}o{zrz-T1F=Oq zVOhPiHWiGAMh>rNFIwlG1a2Mtg1%UzwEV}gT1cckPNWVR-J#X?(vMh(&T7bw+07qU zklx#qnrde7@y~G#-+C~5I=Ey&&zD*p!Dx307U9v@d=hk@EmHGPv)v$9A`5nCY1E}< zYX|JBFyaTCiIwKc_wH4DtR142{jnug=S8N&%+Bub+rkKQNwZbu2lu^GR&Ph`r%-tF*By`CZVxS(0qw<|B0vUBEjvbM4g?ay*J7&6e{xi2BGm znW;Y-0KsmKWLewQ59&Ftse=RTr?!a?3uC40wmd!*^#cAm6tkhlb7>A5QqfHp(Fn8U z4PN;SdFAyk+%uD>qEhu9eylEpH>p%QI;kI3J!X<5VBDs;@q`PuVhf|yL#%E5u{UL# zTSo43Gv>!OagDy`<)$;)=jhZ*uG+VuV^51!nvgnsN1^Jz!WXgmy@}vJ2;?CCvTQ-E zPw%aB?QMfmvlOo2DJaZpM8Y+YD`YaPwdhOG!R+n?n_zj%z!!%(*(+U#t8%jQD|-#x z%Nzu&Y&N;_mU0Up@Q&fxne}hYm6%cXXHH{+*sc=H6f$?_V;pT<5wl19c#DG2uHN_J zMS+|iD=aV0IepDwl@I=8*bBG~AC&0MS}r0=2VK%d5~EY!8f|pEF!LIJTJ7)F?`0Y( z4JeAAp@NU8*}K6K*lJC6jCsdc$Aa~!v^GIeOEF@Tu@g`4o7sN%dltXEd_X!*v4X59 zZ>;_&=VC?VSA56#mkInA~e@ZwZ@XR_Q&bm zM-Q_D$4U#o4@fx9Cj}EeK6Fr4Z(Pe@u_bD%b<)+S(NyT3UfXt$R)yUSPYxPiyVv&T zVqw*esHIvA(W#U|>(Vb?_&o`nJkq+PLfTziy;@Zz<^cd*5fj^Gb z-~6wUP#)>#pSP;W%N-_hV&)DwCO?&rULJR<+MVw@^ev+g%Zmnw?}Kai%Ow_=naW-2 zVlqAc`E%d4A2m(Wh=x&{26>0XpSe*gL|c2qM?16IJp3oOWl%b7TYP;)>4*b+>*rg6 z^zB9N|K!3_r?OQr9r5PqzlQd69dTo}?mA}fAjdf7z48kUsz7EH$n8W~CYSd3eARVL z&_4EP;Efj#kH$O}@A{dL`BwblbVR7}ft}-!>LY4DZ#o}mdc?*RTL~4X3avTCA)l)# zcyey-Z#OwoEUkNrqe2Dm|Hk>McUP^>I)j0oZ2Si!Xb-}$enP^7ejyP%x6!?OD``|PFYXiT-h75#^Ui53 zrWj7@QPi5xRt`gy&c%K=A!feI4ULpm%-b(*b{wvUFc;4M&Fj~@N)6&=hLkGcE?#E1 z=>a)tyx54nd%01#Du2#|`W?6Wz3Dtet`md3Fw>LKtsM6Gs#8x@hldrDOYs+KxFXgd z^w;%-mVlVR8F2k5|MHsBy3}k-Use4_$NJmLwFY7L5pJ-p@vGR2Ci5-s<|3G6elf$0 zME<>uBg2MmH!|m#X44r19tE- zL!cir@1F&BlEo^5>|Le#HoJqu#=2qKO_75|7e6Pp2#U z+=Q%it3VCmhQ@VZ;+5L|Ou+UkuwyV>S7)T5*h!H(M3yFevC_;s%cYAU*mdZ2i)lQ; z2%RK5%+h#x6+}*JXz;Bdixu}b1pq5vXXMXqfEn!OjbrMHxP@T<#3wJprLUY@ zRaLPDp5X@ibCrIa>0qo`dhMQwKqBkIFs`}W2u(67(sPRTeol6$+l8~D)#!|#71S+i zsm_}^_OLe+{P&kdUk{`dP2yZ9`bxgaAH4aMPb(u3{TP=IaS^IJ)^zwF3BTf&uY2 zt-q|(x`W&lMKKHVh1bkEE~(dCh)}KG-H8rr!x9~r#9Ac>zP$xB<}NtJN@yYIyMqs! z$D^v&-L0MfsA}<8*cx<^Tl{8ss6StF{dhGKD&OF{GlwkN01ayWbhxVZJ-b57c>&jS zWAd5h3>#ngOn`aDO4iRKRlwV(l(qkyt~d#t!d1u|wKOK~lssQH{nu?=e)@39Ba4vL zWxBGj1I0hJ_+R|I)ulY4L#LksL0j%<%#DjbUHt=;Wz5gekWd9|f9^`oU!wdK6U-!# zW(NNf7VO=Pkaj6WkrN-dgwMg<$DS#}UXY2jq(@Dc(Tftey1I8JvO@K-{tuxgrorY)<>k-U z5jzVnvp!oQe>>Z#r3v;Zo0x4&x zowbuqkNCG#u)!_U@>*%yH4df&|=X#4{*+0uiE_GZ@(5T%DLAbNwWTP%_WgDnS*+ax>ReordhZSA#AAZ|o zU7WMtk&~46;TX0U%_z+>Tt29YUr#-=7uN0o!9x%M2_x;HUVBi(ww3obcT2NNND5Hg z)V{}y}N!|D)4Z{;ge zHB(vZ*wlq9z={p0C|*nVIHOS=eHg+~H$pIrb=x=vAza%p3GY-L2rM+iIKGLK*c=}t z$)zYeM$pQjE-cc0tNW>TK}8&Yq;T-pbQ#QT zt@_@*G}SQp$AbuhA4lW#6o+uiG7a3RdZ;KV({`}a<*j30jmYAduq<<9NtPcWeX9c| z|B6)nT2O@QvSQg1(00;%hLW!By6N2e>{ZE}b<4?fF@mY0XVY=_su2Y(&V5sSh+rfBp3CF2)g>(tv zMwCjUlfvML!t19%-=jTvuz!@jS#f_?Sp|Q8F}~`$xW1GFM_^lg*Gos+eR2aTbnuqN zr~zIMcbMgYP%d%LPJYMnG+n%Gq35aHuKeCOGZy8zGXXp>^)Ws>p4AX0LU|kZw|}XWO# z3M0f%3b(E{>-en{VULPZN@AiYnv4@kRrHk&Fcv7K|Fb^1Xd)@C>-cGV?m1s(jeN=G zA9;BHKavd-OiTH>PxB5d+wVOH?ry%X6Fio_>0%nW`KEi}q^wAFr5)q3xlfE+Fi6Ka zYx998Q-GzVl|My6Pq1RJg?&9N1rM>zHNNyR%{dUl&FW(h4d{Ol)zO()9E>*K+{bJ` zqxeJ@mVZRDBM*K=9nKL`!lCb=2e@&kO*3Gwd_niEo89%MN}X>^Rt2;K%q}K)2Kezd z+UA)P}TUX_FTi z@RhA$FTaTP{?O@Lol>Xir}9&F;hTdfAG8~YdVCV2i&50dpqr|es~ zKK@B1Z5%k0AmN8$%5r$-E!T9;fE1_h5taz>HHdj6a5?jAz4KoP<{#< z6a3%Z=_f1T{SlG0b+nsMueZ<|b?g5n-cPdOpEtPwz9|3FCG#K3Z?%;_KSE+n1i(;1 z_jVP@q0fNyehJ=73}5m$)pKDw8Of(dJuu_@ouR&Ndli3Itl}Ati#O1J@)fmVQ_VDu zi4yKp!Zlsbno_lqPl#Gv7p|&udj68 zkFSyl;pf8gzBQKqGO0iWaM;bAF;sl-qI4b;jag_adG}0OH+lp|GNDz(m7R{ZdVQGY zWEwC7Mz2`sPB3Gu+8nKJLQIg7(I@ydYN_a^ocZL)aI{5HdVXnS3YMA$2uA9R&^ym`_$gP*mjZtQJ-VbjAzXaLP3+<#13KTV2S^)Z#_hvQI}dw@{> z1wKCIt%ZQa36CGeAb$nEFO(APiq?tB3zO@FN`GC@5Qm_fe$}4mUK&`^5*xOPGisey->Hy41)7ru*hP*9prhrsbBG5gTXc!IO&}e=P3Oh?0~@TD z{L8a0jz5c+zmf{%eX&-di_&VAv@!a8P?-h(Y1CRx&%r6UJy9-n-dipn>lqxE+~xEo z@@&ecCO7u7ZL$~e*pKbXm+w`FEA`Y_4(|R5U=?sgIKjfv*5SCP zBtG}ziypVZ{6x>O`Y2rPg+!|~7NZ?lXMLXcBJvNK7mjQlxcr8M>w4n!xpU`&tLY>1q8aiF4MF56>)B72X2NSzv<5rxqIk>Yx2%L$hPKRpc2022u$pi_-@%b5&s$|(R zm+*22S18xh{g?FW(SnqJGa0i34yy%~juL7mx4^fT>%3dffslS)9#stwm+giWN@9->U{z;_cbumw);xGfs1~sQu~vtJ4ip;@TMk$Y z6j=2G#$kxT=;j-fsSzJ$4%2ECe$zjI0x+z@oq~Q>bqB8oUtHat6Hp7dySay3zi8h& z>T-9s`#*BO{^Sj8UL0e0<#H{lI?v~Naf_IF=|Y1I`%#Q}11IK0nl5jV92o9NVk-3A zB>g-|?jv4x7*%Fof_bkIm{=1T{wPUoq}W+f_2)OQSE?1eYa$O@MF`%5$ty^G6|YZE zkMe!jp@@+Cooo&=CJwwnr6q=~gW=U#Ults7Uc7+|q&O2+=h*I+mbGYZceTv()4@?) z#VU}9c5+PPYl=3`nV0)I+Lx=LMyB_Ujd>A|18OKqUyq{B7Q=9z^Q^wLvw{StIg_1) z5&hP(1y#WBe;y30F}!~#Q#{}hqQYBd*lpczRlPo42!T!yQu?!1)abj|N#^D(PK+km z#Uy`vdGhq19dt^x841}+-gl~Y(`cHyF0RSgLl=19`v<;$ed$4Zk^if!Y1TRYlBtWO zd9YB!evB@`sbk1E8Xd|}*8n+v?D0vv!S$4~kmHr0mHH$`SPMX=g zQ-6lsUd)nzLt-3w2f2+0wr|bUVsl$ly2OCiBh{FbfChT$`ycZi-CH;&G*axXR7Nw( zG&!zsmpTesXr(7Bk>4{lKj{hB{LyuP{nP7t^}kL;+})fnhP^Lqx;-Qtg6&K>&Btxc z5eXCTI;SRoUUWs=oboP+lB$eyA3y%7YyM>SJeU8PGX(|+!B&kVqTupYqh8UP$PPl$th=Pnv1^^Ag<9e`F z6Ly;62W$grVXM!7gjg3%1Q6=i=^|+*vER%7E(AJr!wjF<8);8|o&@0OHx@>|c z+!_%14^||S1V`5|65uL|Y9ZcZvflIO*k15nIDr>S6AZz;zj@*cdDmmeiZ^uCp}|w>$PxKLE0fK z0t?I9)|L*0-h(|Te6$l!$5`fXCLlJMv9o1 z%8&BV^WrI>E&sG8KeRyDkMG$$-drj!U2&JHG{YC=^0MHVi=Pa(1by25`_ovt)C0$5 zvDtUa4Yu5J>b;$9J&czphBVSOLIc_*D8-s~$?7ymc{fYS%6$4um#neXCG|z@e6x?? z3S&@W)LzSRxUgz~+sRNpOt163dB6AT-u^+?J~#jjTxn(=uZClV8rVTjsTM2Vyq5f> zLVcwiB5t;JSL1EX2p@|I^=pn-w{a`)Z6q=r$`UX`JI|1V%>qudk-CX`p3V(uR~H2L#gaI|Ntp zCwD@GADz(|Oa?kBeKW=F9}RjuRV(jPnvv8c(22_H2Z&jG2fyr$SQWtdOuf>ueXI%? z(VyqloNtVz^QGP94fQ+w#h`aH>w*4|7;MI+KLIZOtg^&Pq_}CoB9(JUR;H`8;`Dv{ zD`>}WwKP48c;U?-qkTA!-x?-V02W|4k^QN~X%RPlr?jFcU%TUoZ>Ug()D+)K2y<8yQt$ z*G~exK$X>u#AK`=S`H9Oi@wn~=91^UnKwx4muiZO#YINcEKM}P<>lq)C-%SpN1^9N z#qOd~M+PxJ;)txUSv0$|+3P^Ro~D|+{qAYtOt?~-YJy)MgL(}A(?+D6~!S<}20ytiPjkDsWS!Rq64$v4qQ)Jhe( zKNQ<3t>$e?Jxs|LWUA#~3v$BOi1Z`$IN%vw#e_f$%;0Y@sDR5<0bFQ)Ro*yj#fa@iL&?sGh-uDV-ebNI#1OvQm!zlbdPM z_CSb|#<<`I!)Vzpiyo_HRG=Sih(nmFv3)yiC5fkNrJ@Sy@wjot!KaARjf%+_Y1tew5hw9+!bS9<#A@XO& zI;47pK4y;4N5%I-s;}w#_d5+hx&;V$%q!!Fo&WzLul|{y9%a!-o$oh8Be%U>T|dJq zH6=H@nU$%n3(%NL0{veUZh%LsJkrJ_g8@K9Gc;f&&=g zv9oB@uXu;82$V2L?fjiggP#L5P75ong}|AhDN9OeKM%lj_*)~PyMtXuM`YgB#LVnoU~WE~iA*WH@`SHf}wJ45@N3s2@W&2Af?RH&3H%HeQiy zH?D?a-HQpszB$o>4)joUg@r@k`_&f<@VY#DGb264ApmZ?XKRzWo+5S@WR9uMlXxMR zBDU9q@1YPlC)x@Wf8y00!d$$~{U|ajV0;Popi_p5;DQI=&J&D{?YJGbwYvF^qnJb3 z4Sn^>sXU8ncj*SvakNio-f3M3l9W11TQ@G3 z5;iBt4&j>7yORSD>ezby1;_PVjHeVn#tlZg#MxzJuFsOW)PVa9wm-eh;3dKM00ndc zby$~J37TkJs_lNrHlule`cEM#gUkB+o(A_p9;bx$Al$XoOg1fgVssAU>J`F(e56A# zYaS|*jV7zoxSq>`IlQ)b|!=hz{KcF=7Mx+Ws|MXO_0Jr0f)V7 z8soU$-tXKd_I&t^#<53MvejLFaHoU#nDzPCt9^F3Qf9L>m~3=H65LrYyr^epO0e z1e=0|`~h3FgdHllsj8luhPfrZeK7H+LpRSrytgJ+U{zKmLRsnTC3DY6ZO=#g&U@pq zvHjwc3y)@3L9nqYFGP46$9Alg){sQkj8=*G-93*uam{j4Nqn$qSEM6))Af^ze8!{C z6BQ3WV?ndA)Ltrg#-Uta0o zK^7eo@~=W2;1|4=#Uw#b^mXi-23LyE`cgNMeF>j^(0j&ZH$jzcrecCIXam+_Hgjy6 zmceww?lqi z6f7|zCVq$OYmqmQDmWG5&Wf&iOnv5YJmA+;;xl zWx_Be+CW~T`3m4Hj`7_%qdqu%5UK`%RKnyi#(m_LCwh)#tGKY zrHg87t&yu1l@8Ssn(Lw~r;3scdIe9FJTA#FbKUwl-<2x11;HIOoy@d#i?Tr%&p>io zZsYrd+fzyG3|#$S*z_Mm#U5$u)`=tloCuUH+;NvOBgB_%Hf9YIM2u2448+Y0kQQln zS@n9Y>o(pRn;!{mTJ8BT)vdO`nrn>Q-TXkUVfg@3qC^ZY{YzX>K0i|0Q+=3XNk5 zq2pTBGy65L_dw3*luA9^%&*9-KO+Vrn%UN1NEtJY3n4z}`@ybtKETU8`PIx!hCQsP z>^l9<8Iai{Xx0|}_koUG-i_iC!b7B7b>f&OCK}8tlj}}R zP@dgl(}?wLy9ApFXFCzAHwF|tmiabvhOPwYR~bLlF$@=X{Fuo$8LaW>fbNmsfcmp1z9$?qMx**E44uAJiB zO0hn{nV7yY=d-YYQJj%n!Kt-DpjMYbp?9y|1g$6zZLeL^x-_k<__>YnsH-z&#NH>C zQsX&YRRZ|NtaJ4fUmi|&y?6167C4_cg(-R2GM~I6f<1-i0f%_DtkY`;_|g>DKANvG zUNFm5JN9=&CL~Us*Z*!b1iz$IIrS0nn)!vG{~(pRZ(Ej>Ut|r~e#nMa%7$J7>T*GO zs3G^W`DX0`^;00XoQ|$i^NLsE7oJ-uIt3xA$J|sN1dpAB%oGLv+1X8Lau%%jklue~bE2of^QbvW}N{*~^ z3E!x=&TL2Ny>*0ys$_LR=$}0-H`FfwTcXu=l2w23SQ+9vmpI@kyn2*6_WIOMQ?wCG zo;DQ)RQ@*8I=&Pql)^Xa?LP&U)?fO!$<0yX(|)Lm%^sKYEt|W8&#p%29`R{55C1O2 zwjAH=pqdZ%qkUHUnfUniEl-esRK17)93ztXLWmCrv^_q5zBF8RS+f<~H0FkXzBJ(< z@+FsYv-P~;zk!!6rzz#HoAWad>zQQd>bp4(%(*1o4X_fk2n&>2otkn^&u9JxeZQLB zLH0E4L&sB#JaQF0tiEKcNRUxmhs_(2E|^}K{#e_(tut$e+(|{akeoS$1DQ9E;1#tr zSPTcU8I*U&9E<*A4yKSc7F#SJWCB-mvYk!xN8~t$SUKoYUO^ZN^eXmNEE6^YnA6yG z3Xo*w<>>oUJ|{8zgbX}y0{NUJIbx`coeRjQgj)jE%)$bs`kHWM9_?My{sKrL1uxUh zw9|RfeTw7PtQ@>jASdcA86jJ1L7QbnC+wQmzbBk^Qm|_~Q<+5tgXKl)4js(oDgVJ> zGJbaNx0=p4R+mNY{Hm4F1_RIL5C4D#xBjHJzECjz>6JUcas%=mo4Ed0lhXe{z3x9P zlKms%|Ns7?%J9>|byuMD@Xp|8g6-Q;o7;zSg43X0sPqbAGZ^DL(N0T{jEKOrQ7e5#vN5LKrSmvOdz*U!!#5iD8(U;9wDtX)QEcd*4;!xS zsO$VK*AZ@Sm0K)|uFH*4reoREyk1I3nBlVo5xAP$tM*?ULLxhdz1e1Vy*nc&Q>>!JX)Ze3%lxo!zhTzsI1>%8a+X%7y5OF|YQPpaSFu=6zL43-^B+InD0w}g=~hhuKIS>9MmEFq0NGRy0u z3roN=G#w0J;YK@_tF#P*E7D@sN`x2no^!L!m^G<9k_QGBOS9NRZQHaeTWxG{-Cez! zLv4rfjq-4%k2~TWPqG z8}4nrK2Vukj;6)p=-}jDxCTFrp2B7yD6_MdHQUm`yYamv zc7OIbz1?w!Q-fzCUVyVV)~Om&89Ly+&{x7q+{-D52!TzpAm9h%Y;1&S2^j-=2)LF` zy+VI^3mHaM>Q7MK*o<~yC$;-|z`WeXWigGklqQw^)##aAB?gCLWXEO4iChd?tly(f zNw8mBGtx49NJ%dp>g{=vQR)pd#U}rZW}I zjgEv92so;048NU%fIAeoL7Nm1dm}wtQnv8Y*{N94>Z|Go&x=PqRHTSITJzIbn} z*HHL`TEm!F#KR%gG%EE~y>ZiKSkv%r=Lk|M1yJ35{jA^g&+jKj*M#{`zn!n1eXTN5 z{HJhL-B|4D1v*B1vkaqY-WxS3oycWAl6-HjoXknsJQ05Vuz1sDW<^>J^C@KIp&XgA zc~BC5g={2sr%OjYnSV*kTKxwn>$eNBhbE#cz$Nasw4MDZ)YMdx_Q>{t3yla(b4dd#&O8IrNmq;|8uzUH12bmr9K@@G=S<|$ zqbRIVERBZmy&^3I=w&ZL)}0Z zO$aAq53kCogXxf$3j3*A4n3D|bbGLwBNDyf&4ZCQI<>I6Q%b6i3yu--1rc*8h(k`+ z*$c7$O5W3JBBZU9X!Dx*=9Tp5ChTp9Y{6K-Ghdc?pR-bdm&$VYsj*9wDzm^#i8A`5 z0~#;XuG)`!I>7r8SN6AH!cUXlv9AP`lpBaO%U=UlA+qj`%==&0Ld@G z$vV~%ue|ouQJjCaloF#%EwK64d>LNF2fJO{$B76(aChx|Jrm#D)C_iE_dg*{fb4T_ zVE{8Y!6?C?L`baBTvR*L>FOyX7k&?RRx+N0M#DL($~mSG1QTQy3zbVx#KH}*tp&=X z_}G@MSc(gWs0KD=D)^er0f zaD66`^J)ZF-NS{GYd47fY$OVa`*fId)R;5%V(R#(uof2?^tOK6?yS~qyiy5vb-Zp1 znNVh4YFxXR>CqWN3YXm9vA1>wGVS-*fu>j?zLj@*Xud##tlYz}w`THwE2Gu?zC)D0 z|Bd^9H;hl)*&8;GM1Yb+u)4sTiu>EPN;1pM)8SNt**$rnbT!Z#STpt@DUvf4kom3Q zuxA`{`+em9RuLe7SF|^2srCzBRvn^98=X&SJp9+zmb#ZhV4zDzpXxa2)g(>G@=Huz z)C4x>hK|uQB&jC2V+vW6!@x8Cy4dS3vSqR;Rp^VvNs+w$;gaG|A!g!w&-M-IE|TAI zXge`R&Vb;h`qVFHIV5fSc)KsI#DwAErheY8aW+;WnLL1;25R5O-dNS;KiFASDSiT0 z>#_NRDOd>!ihQx#qhWBOsU-D6{r}U=wFfnIXJI-Wbf=0K0Usc+im@QZn4uIb54Ak9 zG^}W%fbxhN3h@DC0U?AW#3>d60kTCQC@7#93kYdM3=ke=A*RYBNI3 zIeK8N%|669`$9LH+sVv{Y4p?#iRJ%PGYkB9XWio3Sf=V9vsqW?(R2yG1iB1t4ziqh zyobq{@iIb^f=CE8LjJZFxF!o`!a{Tb`QApdN)W{>ggtrV)R8_kgP4}7O|juIsyS5I z=WGZ^;P}b_jdPegLZ@L%k^|Siz#TjHcmEdews7CD2K}VASFk@SBTwY$c(#EDgC?FcX2&O744px3kC4v)`|D4D_OwAWdr9&7M$+d)_D065x zr?B*-H%&VV16U)-%|3T8o`2NU3JEb(jSowmX1)=9q*^UPUDZ*_E!?YdLi0gi1B zrB-(@{k)^Pj1Gc&ne*~4tGqMfCmb978_sK^!~HXJ<2Q7|Zh??(7br>&*u)k#(y-9w zujD%ri$Yf+>svpmDdg^FFg~jOMJNBgGoB5r)v-@;ou}OUp zmLO)%!P=+{3lk^@e17zNl@AzB6hw$t6W69y7IHodYc*ojp}4aZhv-V9!T8M>xOm4R zFxadXgFE0QD{NMD(TSm8=7842g!k76euj5&NRlorzJ^Xo&<`;~^*>y{@zM&t2gir? zPX1MILkrGtzK8}R#lS0N4v4j8dW86i6Z**4{*A+9l09?oB*6Tf33eu2@dial4`gj)F%PU+oa7EUOD$AeS3L z*SLW_h?d@g0zqaT&Yyc?J;E(x8ScvtE*Rg%4j|+ksB3_c>Q(5u`0H!pi&&TIm)HbN zq>m^~QGzd;l8@%(G5b9jOm{w(uqIzAJ+*tO)~S~;8YG5v=QSR_YSL6EoL)DF+Fak8 zEelI@AH0X{iIa&4JtQzLWcin`lr27LQP4{dw}%tE=`m0Mfsy#$LjZP`5zrR;-W85+N50pSDazZy&)@zl|?r!6Ieh1T_#d zu14ICM2y^W96Q`9xRo?580q=t=;;tY;5x}3wCMtB_JH%Q)j2w9fT0`EJ{Lo=E<9UO z<`w^np#%F?4g>RN_AX1Q(vb}^&1n@ARdMZzG|$~Mtga6Xz}NINoxSl^1)MV zVl(^u?ND`N93_KUe{W3IP$)jsw&$rK=2Gx3qF=DYiNWkr-jP2a@L)?IdU!exl;$X;A= zZvVL()_2~EB>_kXNXcFQcJG&^B1|A4G z1BQ5wEituxp}hH=HlW3@P>Z2?AoKk@9e~afoZ8@!phw zKoFNq2~?AwgsM$<3JtF!HzXLPG}^iRwwV6k)g%F!7CdcDp1>9PewqS?rQh_4J zCVwrcPcy4EQL^CGthcoCKj|I+*px9;Tv?rx^!P~1y9u?|1a&uAw5pl0k?=WIL`f>a#kz9$KR^c#-eYH^ z)#S(3ALqi|+EVKt2xn{If453$41!=QYaz9Kk_xSSSUW&f9$BF$M&3Psg> zTi(d8-wI~z3kPm{!BsnLhqVXIKZSRCyGSYOel!(XqL{i=SHGRQsyW0?WvzaM6#d^7 zp)WHAvyAV7l+YQs;o*1FO+U2Ks!RS1mhT*Jcq8s6uf9KB8?nv)EeOP7sUHU$cRUD9 zTHsLF*${VcN}Vf_<-$vM7QxrM$>dHv>aM#2)KHo216kCf=Whq`WQsIIG*_In9J{n2 zl`2PzE)?iZg()DOtAz>uc(-0 bZnWIwX6~;G{LG|3G7Abg;otD}`S1P(-%v}z literal 0 HcmV?d00001 diff --git a/img/image18.png b/img/image18.png new file mode 100644 index 0000000000000000000000000000000000000000..ca7ec8b4c3447cd62902a97205bed67bd443a7ba GIT binary patch literal 25540 zcmce-cT|(xw>FBp6$JqsAYEi50s>M(FCx-AA%r3zAf12^LZpibC`j)eDS?Du0|`Y@ zKzd7v5CTfCK?p_qhwlA5_pdX?J>z`$t}z&__kBlJoomjyo@dT?272mrG^{jKR8(}D z8c&RW8`O?{&V*w2M?B6-4k@{n*iUIcJvxmPNm35V=sH$UWk8CcUJzsgD zVFsn5qW}E+?_8Hh$#W_yJ2TBE%Em9P)=9L_Zs9-eZmLIV-MV@=fy%I89u;@PT{-%) zP@d^!)r%hA1@G3GJ`#Luq9JtA_*UI{7ha=)i_Ndvdy6hz$-VQMl^p&R#CtdOuXFG6 z@(hj!(z7)sxvyM_TRjSvc39|JJ1Y*gi{sFNteq(Cv%#E|TxsI*l|Qxbv~T`-_Yr*g zY))t8RpqttKNTu#?yKki)LI|kKL4i@5ccq|Kb2oJHkbcYeloUS`&0QY_&;oD?&`kJ zthvzP8XFuLz<+FK{lT#`25?IKyS2Pu$>z6fcJb;vUDVCaSyS3@@GbNqj--@$Tq+3O-#Gd|oge7&%z%Rve{QmhXuRP=SYiw_hv|F}&wC&E1PUjaT z(5OVJOek~67Du{R%?PLR&F_EvGdt;vj>oo*6yDBo?rx#ZC4F7e>!&_#QhLF;ZG2Tj zWvNz8ZJy7jzE%q#sU07Cw1F_=(^(Tz0s$w7=Bp|A8lgugo2|t5{OXf!BN0`i33H-R z_Ki}L#ZL!^{Q%nLwnSp(AULR~Ahph5R0F;A+>6~pvCHPkp7`SZNjEvogMvUEy=Bgp zy;!7C+b4`n^LHrBtN6v5UTO;cK?HUi%^{vfOzY`|8a)6I{}v}@zUXrF2H4=ib#!~F;`6eNEf3E{oq%N}V>O1#gQ&+zEQGf%<_&5+$ zcS3Gp-B0Y>@(<~01#U7}5!(5E)^gf_qI!Zi*;or#tWQl#O@g5oIopY5Cy%h1yJD*z z5~~ntvCb=Zyr!*(+y9y+2FkwN4hUnC)v4;*ZEZhn+S?m>R&Nf_J2mISV|=S*OrWQd zL!zr&v{5xlzpANUUki*whEn&}ErTq{74d2=F`Y8=l9#*F#(`}>qi5Jq3mnWUPys7e zWj_E*$NUIgd-40&P`#Qlk+ln#{_v#EZohVntEyurO?Z zScu&!<1KF-uHQ4d->%oa+Q^AFV9mVA`1E$p+#8M*apg3hE_u10 za(R@_660iP9-cnfqUW;XlyI^zaN+kj4JNfVT*Q8~(bYMzq;x>$^-``*C?G58VlQO#AQmu3G_rEW6f^1wOz|XQE_$8(#2hrKSVrcB@>m z0`A5UWz|Y`P=v!vicH-I-DmX`xSdI3@2544?~1sPKPl3A&$U91;rA*$@)S%i?fw>` z6k55Ga42wppa@QAqz#9H7~$`u*;glt<25q%7r@WEjXnmxJbY0xV{~|&x9(P&blyDf zFKuF;{d7*jC81U1S8!2343Pf4i@DLfPnz%N&z{iA+rUz&NWJ+^(03QH5k%5LQ1>k(`H>BvSfJb2kxY=3;PjeNp@Zpvo2!4hxRJLSk^}4V%2&r zs7HEFtKQwXZu4=^>#cyb-(RV+Dn_`(3*`@dO2vYtt!?H-b?y&#(f|JPk>$~CFPb%8 z=U7XF`k$$VLMlC!>OV5~;@*(%Z~H?<^@~R6|6kSpf6WH`?;7$N6A71#eM~HFVt|d5 z#FA8J$(n-O&w%iMtX7g)-T%mb+0VF$9gg+m-=A9K#e$2RC^@+o!ti(TdCuB9&8NyF z)6=KLPSee8C8J;G2byOmerO#zW(6HAT~v^BK%{KM`v?a3{pvsby9w9`SBp_S|x=NFLKHf^Rb0HMPlCkJ_l3k}~ zqV#854d|2IZ+pFHK`5QXS!py}SDmVe(#KIOg?$z%G%5%mGo)g0ptbv(1o5PAEv5yW z?+BAZQxlT|phW6>tMmSBX-&_RT#49COmLqqpS+Cn91J7;yeY-QJC*KVo81#JvU-m) z>(??=tRJHMRr9#+=_zL}$D6qq&#GrOUe>+3^X0&7)q15M{#0a9^yp}lb|u;Rnr+ei z)yIEE_-Nly%jWB#xsr_4=;)-XU}4D2OtFCHI8C{!4Z{ANpa0Wf)djbj_|cUP^JZf9 z;15TkU|y>YE+1xCMFm?z%Z5EP2fU{NPafYr-rR7a1d}>W-N&{?#i4&a00r;8MF?-Z zA13%o2`%OQ)1R4%tj*U?^BJPBRO~bS7->*|9Uaj_!EQMZZN-o^(O)?dawBmJO(@WifWc<+^E=&){&EHHNav?Bw<0qtU8+ z^t+9UOZf9qi(@VyP71}H<`j72+{Br+FVp4u-FxbtBkb+?kGRtmc(=z{Hz_GtyN@cu8%!s6jGpPlpTD=U)zY-C zaMU8lyykzroh?WEXDNGieFn_rZKb^coIB^si+u|baCzf!e zL!EH_v?k7(@FJGMPTq`xBG{k4?x$)M+iM(4lTz)dMkI8DtJ*G8tCq{byqKpUm2BlLNXZ6u`kvc1bB*KB*K>%K%#w=9ECn zNxmLWXvIzF`U~C@apA#F;9#r0*M7U16%z2KJ8*sT57e0$+5@xRt|OD+E3Fb9+;fwE zJWQ(lrCJ_Tcymuy%7!|wA_E%`o=x0VKBge00hc{#Y1W@wO1-E#km^4*YKw0PUsV<^ z|Fdw9nv7B4M43GT32;x;Fmcv@wKGiv1nY&|@$@`q!c-5wAi>x9Exiebhw#q;*a^`u z=zFw_;hAuNV@bgm>ajc5qmQP)+_dn{nts$`t%t+K!%Hm-;l?0F7H9!yR$K|og-Tjk zlRukekdtI3#qy{6%E$oqua>9MV*Ot`-~T(s`~Sst;Q!T#4A#V$bca5xsISx;qp5sN zO9_24elOkf#U^hw25I5zt}jf!*Tm_eOV%{NBTD_%3W^}tAg`$3E12Xv&v$iPh*wcS z!KV~guKmoftgY^|<+>aanEmRL-e-roL@{=KJW>Czh7SpW_tGLaO!or(MrZY%C+j*U z{Dw${k7e@#l@~cZazaw}Wc}SxMlo1>$8RzV*(f6odyrRZRPrGf;9!Wcxb|E>zw_H- z;DkB)&I>mhWMSMNMRIm433$V8tv$GxdJmG)o}sbVK&t~jd60gpMOpwCio!E<$zGar z%?|cC(^_1XXrt~3QrKOYylChR35PG4TAtck6QAg60YPg(Kder}J!Jk@2N=Fj$FN?| z*|A5g0KcG2>1*d1@Za99uq9Jr<=jlPAAil?!(yk&m~pgpB_WfZPa>j_ zjH=a*0_LI(%PKA_SIU(n5dk(i#afY(E^8@wtmikIejj3iyxJhq$$c@wSWS-7CvzZ=?sNh< zQ<&rv;q4tiK4`TpBBBksJ4sBlGu>`6F0b+aTs~syfQ7;}><+YZF^9YI3i>YJ2beQ) zNWWh@5@GeRpt&u3tyXCho=f#W5WHTD*>!Ts-YC`7Qr;uo$faSZKt;Cc(^t`TYjGfO zA@D=CQd$SJw8W4oyfWTe@z_o3RduNs4EYY%GPrGo)0ay+vdT{|DRymxBmj{KD-!E@ zQ|NjFn23p73c}u_e{>ReVZllO={M_xsbA3IeIT1x;y(kcEEi#JmW+<)1%ki&qMSZ!MR299lDAbcu+=O^WvEx9J` zFc9MVl3BInb2bUjT@z`9h{m}#Wf1>zM_W|VWpBvqhq@;wASy>Xb)dwd%N;w*<=*5<6Tlpn7;xSG%0D++Yv zOlz?;rdD_frln-;x+fk23V;ApAGckkl4D>5fCC~IH+tjM_a0}Y_!w-2EXqbNGt zoktr!G`%7;13Li=-;aZyT#S(!Bs@_ZH2jiql;aQO>gsp(Z}No%U)!E&E&Jf!TAP_+ zdF$I)OpCa~hkXUHHi|k}SiCaUWksSeie5hl#XGIKv>V^TI9so`zYOG+k1vd_hqj3P zRxK}*qEfhRg5zYf1^a!KS;f^3Tq?15(}>CUHZ|^0?W=nL8}uTBpB@NTg|&*IgMZ05 zA730H?NK+p`{glEA-U0)RPjF5VUYGOZWfP=?$DCt@u{`FSb_$ZUaFM@5gCpnC6OG0 z%#YWOCw}r)nTid#7k)EAY@zM4nKrz7-)HxZIWLZ1cOjrMEE0t5hI?6e#+YTt?vEi0 zI{}i6q%e;aUZS^B-MblbB*?ggR1Iap zbh*b{l?~`)`TZiWz8ZcKno|&p%n(!1Wkx#}>qVC?r8TXW@l!}4D*gM}TZjb&r(w(V z1awG`qe43WxJl2$)A^Pqm|GT+l$6)1?arLOqRS?y{C4CfAjmD>b;RA zO=zOw?{Q(v&KZZ5{8~Nu3-gEbwE%k}FQ&#JXXj`O~f`o7X$MADYp zYpa}8#D<7un^c25A|u9KA78f#%%-qCm=86^FCT*y_WB;dN?4E!hLT6)HaV$lDVpj^ z()AErx3tTVJSQ#3>UwS%Li81wUP*&VNr7y+3%WDQ+N zYAz$76{4B!&*ZuZ`URVy*6OcE%|@&?4bC28M99IhrB~Zan1m?Wd3L8o6c(lGksfK~ zzdTIcFIzi3#-I()oHaYhX$po0gEMNhFTkETPPyO2T`PKmdj~f>t| zBW{h96=lqGc6~3_2f&BVh1D$~)cxy#wFn{HZj8GNo51?f^W>3%D1!n-v~gFHB_kfN znh7XpD>1+?6@F6j6D0dtFqJm?SAuzf&8MpnuTBQi2{OTrqgI((LGt5Tt+O0SEU(SI z+!1_<|AkUA<5*P~E1o_JM;i=5JAcsN%X()rXmgCO4Rni{9c%C~ehMNc%4D?aRJNc$ zAKk+nh)dz#u57-&L>kr<-JP@yE=E#ic6rHLTA(wve%d3}2q7u7iv;&M`53hyWZJK? zPgU3ZWU%uGrm)6EJs8Tlrz$?bxYN1MV({`<{jap1SnvPb<6nGL?07 z_(()-SnXgL!R?$F)4e(N2LwI7x{My7)5ZJKi$R1N{q@RfV;j-F5cp~(cbk-lgi;~D zr|*Dw@e0h+8@j&s;rWHO)7>W1#qie)zNW5LiQIIIM2V&P-+0;`?fuItWl@EaJVoGp zTEXrDfwg*mYuAA``yS7B7VrzfN*bZ3ae?(L#QILzs_C+Wr!|?A&w4%wG2S24#^K5D zlkWV*9O{Zt&$TFvju0$08?=gqoo9od z>{WtB){v}9yJiZawuPO+&)ce%5TC=Ewq5!)0A71`)QeXse$LWARO~t?HZ{e7J6qFh zAh#RIH3T1i&xZTw;$5b2lczsKl4?30aO#7478g!Hvv9jaOE-+*uI9FP(Q@&AP&RVEo#Fw|Jh*q_OhHN`Iz+*sp4-GC@ALw*KIC z(>Io!>BoK&d#isv;0r9*cP6jAa>n z;bMhg#pSCGnH|T+goWskkfdPq;-vnCUzP5KYV(U6oM#()-*BE>u+@~Ry{@jM52vd; zFs+-kv{8vSA9+J4a&AI2E{qH|aJ704G==1b+3q@Dh#gyK_1YNK>rfQd_>kW7()F;s zkwXI(ks?C05h&5cS2SQ{zimEBjaebU32%ReG$GveXrr4shC5lVun3<^G)z@ctt%daU5*-a8>jiA3~-a;Qq+AOShAJ>f^SQT z-&aeEqm?HFAPimFH%#Z6UCM}m=RV`pA&s)z1-$UAJIMVx!J4KppkejcqI9Dwgw@;C zPL*AsPy;VsdAIql=cg60=zDu7N7nE4mLlN8$OlJBN6@*G6Rf3u48jekMq%w2zxw-l ze810Z^A#*!#4+`et3n|4uOLnsw&$r$8w&~2aBPM7o}V?^w5Y|L9+|d&T(cB<_h}4a z5|OySx$LqWhdehw<&i#8Rb<;I3JKWI!J%>~_{1umlO??9bHM9(4*f^%rKj-ALC06ee3H8o3+k`n&fM(cVR6)raql zClwlKwd(Gca*drlt&B?eVWo@6REP_EY7hj_(r+ZOxWiN!x7A;Im_|Yd0x~_;Q z=qiM^7vMiEK2i`btY2ArYm`zU@0=Pdj_`5qQ2V+pAnuyIo^|WPH(h(D?BG7Z4 zh$vT@3xa@v8p_<`qLhyUAmDQyDLU3&@D9X5a;jcWyVaXOjg^r9$*O0TEB-)JdsLFb zGgqTcAzK0Oo(VEYDz>ZP@_0s#fI4mQXQGd^(9@NtnzB>0iA(*-3`SE5tB{=$1uI zW)O6sZl%^f;e7lT<6W3tyKYP8e|A(a*~jm{XEfMhg*iElt(z5j4(fu8wgk$}(56s6 z{UIXTB*a*kS=L5BW1+R)w7V7}m2xfY8!K_jm{(W~t(jAqT3ocSW-|KFT$DLYYZ5ii zy5pCh&>!R&ottm3^cR;l_pY5W16>_LV}CHyJV73)$tEB;7hsWqD3s~VvI{!Q)vg2V zrQI)D3qW_a{Rkaj*sL5$V7a+XPHi%xf_gy=l5HwE6S4}Ma_3k##jRI&c7YV~fo}r#e82_QG)c{s&LKzM#4yG&*T_J1RMIWIKshE2g4WIttwdKyED^$2qTbbKNiDA7bCSd~$u zEXg!O=&s%t`~1!%K|FSmu#kkfx3c`Mw*JeM`);qFUxOLAzItX-8B9C&@L}8*Lf^hC zyx+b2_r39s$o$=_P5DvYdyFIC)j|T3c2sLZ#uu%d_q6CHhqVSFyd7QI*(lA^bm8N5 zGiS{B?ns{KqYNc}g}~Zd)l%0IbOOM#tRK!(%eQPPJ5LIYqxXr>kr5pr=XSYk;*=2> zXl(`|i`az8Frk|ZK@i6E_t)bVKO)TpN)2OMSNv5Ph2`TAU*I*f0O2N5o)RL~-- zEN!|=)(*U8U8}R<{;S*g1)D$xyzZ__%zb;C{3-M8@{CEm@I$rG#kFuupaEaU8}P^p z4&>+GDZ7qEW%@N-rB|V;=9~$ypuu3kgP~{VANEQpl0`C9dKjS3zpbaR!(k2WC(ERNhMF6F#>YA-&g)( z=AW72IoMWOkn!g+gaV7cy2?7gAYjM`35NB~D#iBUjQD(5%-EB~r?6s9EJ3~v#E`y7 zkk?<3p0s$D`a!A9hYoZw((KT;J33`q%E7EEK-Px~Nail0t+2?*Lt)W&04EJ8yx<(R zPCO0;;h%k~ih6kNHxvHd`VVhP^=eB1THP6Kg*X<%ID0d6(*8#6XpDr-&sb!dlMBJ1}hIr@y)Mg__^I(pRoCj4O}*@T9k1 z>*#rdHzaA@uGzqb(v*wXre9Ajj4+ zo4$W0_2M9CzvC!XA=&=l;eOxFhNbKeHqdV(YNGz-+_MyktY4h3&*<7S|BL@g2R4A- zLO5(sWrUve2>%P}zc^^#e7vUA`7igu$Z7X4oj?6gZ^pNXaI)v(ne*_9DEmhAALi&$ z$6_?gjGjHqf3^JnY^Q#gfR2Vsp5|{JI{eG`Umyy6X`rt@y)FLFw2WU)z2x5I`nQu; zG?nbpEN8?_(KW)_Avy1HY0idl_GEl+&{ze@zy1`vu`~N4SC8MOM*r(R_agE@l^Nwz z&WZ|{Y9h0q^_KO%rH*V5bHQj+QO(VleN5waytuNKPR+176NQqc*z2Yz&nl%bbx77?Nu08;vwgrpB)I$$ak=-Eh zN;74^)5B0&@^rj;hmFtaA5_}$71EV>&>)p;Z!dYZ+S1Nv?Z{+j)oSI<9p8QYxZ~M) zRX}@@m(hhz4FT1ko49_jCDn_Jp5Zj^vmbPSqhyOWs0S&(?YeZA8C05YZlk)fWt%7< z$E2w|rtABZhk4C2wM@bM;eqF|ufc8-v;{UJ8O+&Yx=c2YCGF)>9|LK{CSO0x)g7cr z{w5ILrz&DrRD zA*~Dj;-ifrkq4frgN9g8>Y~ZgTWm-A_Rbpj3O=a$jLx;U*v!t{f^lk16KbiK4#pG! z&i;jDmg5*-y{X}nsW!u}@iQ-z4<^BtrT$A{D_d>O?#c~)U$|-LqVaEb+&?YL);+#S zUPo4IM~UKkCd*i2;U>q9NBcyzx26*#5_>-eSRV$~VxM9Z50-e~6@Ps*;ckGvJzlK4 z#*giByS+sj?8+)_yA^(Rn5az@7OUu1@oUS3EmVH zKhe?$dCnVrc&P&@ug?CY(3Q(=O`#bMfAjx%Gsb%+ZpAJxL#XJ9I#FP%zr;a3qZX@A zQ%cOsr&kTDy@Q=^W{fN zfpcV2?g6FZFpY5#g4#d`+U_d&bXq{64UT_5STDu{H%%yC?&rAGD#;H*ECsk4O{_1OvAp#iJ1)Nl51*()DqblcI_yyaF3(9jn+)Mf$mm zCEE(vapYf^{;F2bg$zsI&!Vox4$n1dH4<{Lju*<+=pkd1j<5GbAKg^E5>V>@d|3lO zcr0{$u!%X*34&T*Dtp|uWR{+5>J8vA;_!$~WE#YeR8HO%6gQ*g)8@dUhv(ggol9>PgVApI zQc@&0ZX&geB}xT9yY9?7!?dsUF5<0!T}N|p`Tb0fsiI=9r0@p^R+1}t4Tn~5G z9eP+inFKqp$^GtsIb$_ShFk`wtBP1c#v-i;k7{M7bIVHNH78o< zE$L{oKalsL!I8C+#XN$!c!-qlP`uS>oxOi#r&XJ#iaSR|*kSvvy>_XL{VLMR_5R6| z=mw>s9%Eau)7ttv;78k@(?p6#(pDecg#5M%o&JM@zj)~Koq%E=u~jCi}yLdcmN z7Oxxf;i*}K74s|BnTgMM(0Z35r;SLn%ntR}WVi5-qjz4feur+z$F2iL+$AtAl*wqz z<;naZWel^a@ZqOFgha%XO zG=`4OQM9GbGSf6I4T1uh%9q)P^^n=QXLUw zZQA0D4&35Y4Lein^r71txmS6QrX!jZ8&g!nl%y6duOTHFx&$j?e7AkGsP%E745%)9 za{EL&>q&~loJRq!RQE!d<(O7Wj;~%pM%mC;GePe{FE$v*wW1^z?Y?+Z!Mbhy)t!Uf z3P*D0;nw%(i`}HYfS!?$>W4_(77e_|sQ%{X360umu$Nll%*i6B^TFdlCyU55@KnTU zdTGfyOFZJT^}JQ^@s8gLvUsaZo+ySTld&6K+C7c3Qm8}HNP8h8dE*076`_(f@zgBs zm3Ku>wzY17Nl<0qhw`l}mq@yy(ueE&tpa;FCCL^>NfL!f$u2YjGI$Zqq&-%`oPb|x z`nx>KCl=Kr{v`Nhx;cM*6daU0+WzKkh2uT`qF!%EcNT&ZcK(y?w0=;*a8&DX3Y=PC zd!6Wg8Wlpx+~0SUtt3WiO`Jply+(MRY8|O@p`K3 zK*#~IU)^zmH8ml|bO&7HKxZz;M?K1q;iI?Mc4H*meZ+C$rny!?83mFm-a#+L)uZ#H z`s2cQ>lhP|AHSW0=_Bse5R;xo2FcnGUsa+9Bu;}ZTPnQK3@yeazRdjGo+b1%RcWaY z*)z!!H6cujw~MMu%~wvqMz32#`YfLJuf?viIA`|d*y6quKGml`48sGIS~cOjjQFNp z*^1l`4C@i6$y_c*oeC>2AwMj{lL9}`wBe3^-BnOm^7|osi?G{1!czekI5-f^wh2wd-U4c*=0j|A`D1F z%bdUuS)~jR*K_D7oym2nj9SyQYeUBOskevblP5dweERfEFXVXTN1HQ_1Tj{6U{p@# zEcN6msI&b-R3?eE(r)kB0U5NJ<10SgVC=PS%e zX8_G>sa_dTkjhwWh{#`qo^~mrQu#GaJ*YW_oU9EoAJmh?6sP9u?sl8D7*MO};Y#j7 z&mdT)!lln0hAZFt8k~BTw_Im%hKbuhGCoEL+Am)%l34!0mT`-H&GCvNTv;HO8Bs#E z!=sBV;yOqk5ig?yrS%MV0h2$jx5$z??VACbw4s=yupLemH{>p(iHP3bBo|+~^#|Qu zc=hFjy^Y*sbhpkf!1ZG4c#3X^WC=>j;jP>sw;p+REr~3FzH12B)NKuUOZRwpy%)z! z^l9W(1-7}rfhrXX93djIOztjk@XDN1d%5j#E2moU^x+o{VBx&S*YE}Q zzg;P*pU~X~oy-m-(1J>hWphobA1T{bF|TrHWba;jr_T2txBK}Agyf-Bij zr}%2WS$sYZTLNJ8iu7dQMd*}L(L1hhOwaibe)ivjt#K8Xv|l<@Uewb)aNa7t0DEp* zCQMsv8L+UjdXv*Jyy1bQk~yGn*iS@aQdkJ|6Mhh1Uo+h#aN3j2e|MvPRrfyv({Rza z`m4+J_B8Hd-nE1kOrcuI7{U!SvFpuuOXj3kMAm1mO%I*cZ_(g-9A0_mp{SEAZp8$8 zvEs1CKLGl>NSj!WONGw{@=(H#I&nvz-@`U|`4uq83`{Q{3YkgXxHJCA7>-pvyH!M8 zm}s^|rU(N@n>AU7n!+$g9)J%0STI}hp;{p92q;+o@&^lVnFd_(8rOJY8Ov#AS>H_o zZkxy^B)0utETNVnm8rm%p1E_Pw7BGo_5n5}9KYI2PXN1*8HtD0ub{{_i4s4;WG2>d zF|DHuVY7g}(!~08;VZ>(cd>#9|vpg9tCxX6+BXYTPXc1KxICn7J;U20CyX!KQ(}8sk6{G^84R1oorUGDY zeR5GzXNQ>1C3wEvR6c##hhHxhPyZm7UvjQWD7CqpR^fH;nz5Uk>$PIl%V&O@B%7%O z#0ac(8eqJtbZVrnXkN;YS_wU$knbH`eeUbUMetY=%moFasD)jA{C*M~vG3+LAS|jj z@ai+I_=)d~50DewKJmTx=fY>U!sJiJ=cqbdkeyRRGfRy3*m1$47Npa8zGt6xWTeyx zY=Zl|A>jO|af)lgXh#HVOxVjP>}QT}4CZ0_yNno>aq9BEHRlC7zpo(`7Wh>v1}TpacdjHI^IL+6=_>DPV0qSo4E|qi3l3mwqZSKz@dBT z$QuEM=SN<>e*MYKaOKxCL3{Z<2D;oV{X{Rna!h-FKv)NE0_p z6eC;IiEQ_@<}Roy*`59G{y?uJhutRSHqnS1tavTYT5H0a!ZU9tJ2+K}sOtWxb5-l5 zXP8m*$3gkH#EXY~rgEA*ix3kvgs&0-Ql}BkQDiiP(bgj3Td*E&e9dZ^wbloo!PX6Wfx4A_vJuPnxc9Md4IPgQs<$e_ zJ8^FyyV{gToo{~a(#=4$l|1+NZv__%PLb>zQoe4E7ZQByIgO64q|O{ay%LIWwKS#f zU~q+N{l;})(U6CX=v>FlEOIo4`>^_J%)toAbd!22p8uvZ=)<@m$on=&<==|}3j3O) zIAXp;O?N<%yy2$#x2y!7g?h#@vzvgSfE*4Ei99!i$$Kt@4bX}ZS*gQVX{g>oS7#Ua zgdgglk8iWq`u0#)VY0_^VZ;%3I;3gdDEfK4;qd!#3F$;PXUVUBWPRv5=cGCaCDD;=hv-Z&s;lIj+@0KFXYl zXb_DB#1e2|af!U?l8?R(#N8mHf^5P4tVT%Z$R_K4EI70Qa2WV;jc`eh??`WM2cra- z%4psEm{_Rs*!ibY$|rM}Dfj~AP;V^ohizDIK#<@a=_asNU3KWZj- zrEs5RP%t^M%)k<5ek%MM2m45Mw^wALZ4LQ==U=S5c+g6-vnleuRI=rN;ppRIcl4sJ zc?e+tO>g_STwDIwZS~sWpfk6T&-H(>@mHgZ(ag4|qW^;2B|razZvUeH18nEzHQm`dX&8>jqNBVB3Se_-B^;Q#3AKaW&ORsVDu`yaGD?7!%d@a3bDq&xrKjT8kjHL`^~nUq4fV36Z8Ii3go}I zl!1ee7mM0@E5-^(ei`}XcZ8Pc3#u$p_ni9LFSy{2MOKJ4T6x!A4YChs5OVN!bk{L~ z&pkS_7MbKEm)H3m1Y{nV@Nha6quibKTz4jh&QPhd#A zj|LjmTO_|?^(lsIS!Cw%U~I)w-FvN(Um6`bF?Gt^G5_+$VBFEbD!g=i7x#Dhl&4Nt zpY2xwNdjZRNzJzQ>m0;VQNMOdAJ{qQFwPDyV8bp?t@6P1p3!pXY2)gaOV40kl(#Zn zeQQgqyR*}3Mps>Mzr3!t4k*K{SS#7M*q(W3b;1+`m1355R}77j$W;!0`zORR$s&t* z0`m~~ku8#Chx9glGvl{s;?`&hOgfb9wws_Jt^8f9C0{P`=U2F|!-_L3pMw_`f`oli z%i`W@z}~JR8sc}^pI0(C+YG>CCl}=`HSKODHFoux3=NLi7ubItOJ{BS`RZ|>CRy{^ z`Cq2?fOnA(mEiYz=QZ-a*1}qh=(VHGtrGRGok@?Deqn}s`ru|dTXGFa$csZ~yikH7 zrHGhkx%{}SfI4Y&{rdW#e13uZaJrp9K@`HJZ~BG=1b?o$-3&8QH&?U>aO*UO?_ceG zT9(>%Pe7(N!xjrO`W3)z5QAAC@I6#9NY zdql&;3*_ZJ*hp91sa)8T=|bx8U6WH`7-P*Ut!^g9l$wP1#gtW3ns=K4=GW8Dg8f7` z*q@(8VV4_a+0oUwCMQ6y8HFSV-S&D}Zsl*6NKbJ8pbS?P{33MeyZ)jC1a+S>P`62e z$tZq58`0y4!I+0!bu^n@*U!M&Mp+>?0Uh(`hC|HIM}{uRV&pi}f*b(?ypU2Nu`WsmQunT)7qD;d6ierG5QzZfj(e^9KiA zixLR>Bof5njeg2i?zdxp zzrxiHBz35LC`&SH+2N_RR$UsCBl6eysC4YSHQAZjTUGgi$7-xhH)0ZS zrjayUGTMG1^07+1c;m;G)C3pZ3}XdU^-5Ytz$uxmiMtJybQrMhXI(u$RzzfT>2{xF zDjoUu!@N?OPjUvweiiFve@s!@O;XdVB0#`u)5j+CUTTub8_L0`Z28okuzI%-U-QRw21^mB z5!ipYvcNvbMTA#GnH&Nb$Jz<;nGhv8*31nMeoI1}1 z)Kec#b>2x`fR}=_@z7qql}YRD+jqjHQhd$pHb?bqEYjGmOXmPxxDr^Muy>R|z7d^@ z7*oITOofZfX_r+bjr$E->zA`PlLMOH9nf=>e6svpf0{UsXoub(dNb9WUg+kDhUMNr zyz6A#Gfe+VoCl?<5_V=#ZdGdL5mfJ?kiHkBf?w>88BJce0I+p}*O&Whur2nPjPOg$ z%4NyookvO>NC5d(w0p~ufdNJHi~*DQ;lcq_IdIREYz$7la26zbUqH6TAQ&#Ls0o_K zo}d=jzFoC&TrKjI^VZYG23qfUSg3Ywl{ixGW}-GKoyt!bcJO)b@e8$|&%&m8HCf1# zCY=dqDJLMfg5({O=mD8LdyjiPhb4y3m5N*@pa|jGf=JtqM&M_zm9@H;U)}K;hwilJ{m~9_Lct`kO@Y5=K=Y2UrP`$PY9hqpp6SHnG zlQgc?eeiho?}lKzfuvhL0d_G|d>fC7sC?Md&0JwW*DiNRlseGtPH^%XMYE#FZqM*W z+42^L>_$C(v30}EdbJp@@#7XTYl~o#Szx7jZl3H0TE8LuAUPFG@p-d_^T7 z$h0^+Elp3mVLGIijFn1tHDl8`hVSA#Y%=GZdoUlR6hnl?;v=11fSa9>t3)%y`ckAz zbaZghFu1caHo62C?KG!A{4@n zb*vN{s3?m=G5^)tUFjWy%GlvfrcsPN1Q!dezhtaGb7E|TX~Ef@*|5|828AandA+&K)V>0UXxehpubmX#)1$Szs= zTSts0Z53g+o(IX^^#}9k7V_7qd(d%RW4mm80sy+wu$8c%Jcf4Z8`}B->W_hNAlRD* z_RW>W_?rKemA_eKkw!FT&nRm&xi>39YRY)#htrNw-$VL{3$Z^6x0)+^T)ew@{K)U* z@b{(RUn!y&B`~l&HF=z+0`|$$&#iI4nPmHmu`DwU0)Em#kyDa`7RGyI7q*oOX!b0w zy5H3`JsPp=vR}hN(}Xb$^KdgjF^Ci*eQ#uf#sH_L-BhC}4|$H*C1m-;xf zqzTF3==QB7R0%SoMv17`)6ouN+}a?AeNdh@C5R{gjJbXw>Wfh8h{fGZWOiM=Vkt9{ zY;%^gwfY=pScS5BF4FVj$zdDA0}EyohJ%HZHTmEb z*MU%|WJh<=w=vkH_+HMolV784+mNhg;0 z79^~ao-X_bH);{G`6e|;*z|+)xe+rI^wu@3I@h+~jyFPGMq=3Kh|#iYUge#HfZLmM zev>pO&-by!oHzH$#@g~o@%juyW}|KkLx*dNUhh>#)bn3Eo4%fRtu1}38~3NaOBTswhHPY@s{kcpWYg#+$1eX8+> z=QG(~%h`PE1Df&mQu`pg`Rk#fFBhsddq1u1H(bRRmO?ZnZnrOfp=_SL%F#fsKMpXg zB&zvb01pi`)NSytu*dKntbl`*?fZ2YCgwbG6VGZI9{2;#DoDiXnUec=MW2^EAI}V} zxf+;tVuk{v$KqYKd}FT%+g&?sEkDS{m(aokBC79o$J8s$&j@i(>c{Ib2hv*8Gj<$! z{JxRQZ|!YA514~3gYJHuM+W$Tz0~vK^18h!R;LU`Y%ylZvHGOlOwZcpqIx+~@Ua&Q zSu-J2d+ZXE0FvWEH508YNsEn$ovzl+KBTfK_}N3y_eU{DhvY(5a{NnIIk>924*xCi zlU3WmOJW^g9Y~{XbiwgC=BplcC*dXTmuk#=if|>O>8}>IM)#BtKN}E>sWG=bn(;Ur zByjDN>m1Q$(T(RK7fyhTmcfES0S$09kV$JHyuYn=J{G^7tc zNBTtp^@5XjZW*IL2aHSa=`q`_QYFvw&KgeVu34sDYp0i9qn5qdn3x-HmB zIP6Fk7VrcKweSHPesE;~qzLaeIh7UbEX;&@*eN>Ga*1yrl%F(;805Pu19vSty_~#w zJ3R)uSXy7=BxqBA+eeY=XNeTpm3^SIuQRe~@n-RYrQ(b}V$4rd)pR}+SSNP##bRWr z&vWKcAYvM@HOwu^pubX%p4|%AQ2X8>zXKHa{uom+ZHYGM^l__ux1?^o&iQ6UV)2AS z0n5wDbo3D+PqR3|r?UE`GI@Gq_$*>)IkS6UwU z^8Ng9u`{Jxg={wJXj_`!;HbVHDRgwoB{&|=L9-}yt{KhPu`G{-_4c`9jKG0HYz>uG zhl_Kl^6pui)sDfnI;xzs0ek{^n4RutgMFLd*Sdr|Amj@S^;tigz+3UyE<8I2>OCHi z=Tx8-@>6Tbv0}sy`%C=07O~l;a@Qv!=Zvzpr{`t4tKdp6GgG}KRzXG2xR7r>Og~L; zwbd3&3n~ehTG}Thk&4~R`J#jdsw0`=vyw_xzHDKRl?3SXk_Pi)nrxGcz507i$4B(D zb<^RWLV)eL3Vxu;aL#q&-gld;Ug0KvO%lb;fWA?px^z^cD16I#FIveZofLuX428*+ zmj?^uN{k(e#-@rTCb0$qAC6y4(;ZpbcKIm?Y^~wxHhWGH?fq3xW1)kqA4hjiTxgZ@dq_9=@KoiJ*hT#n1HH?BnM{p8KH5B}v~wlIkG$25 zETtKa^z`cu6!@iZnM>U*yO!og{zI2`s(}!02+n3WaVYkA7nyX=BgSx-EiX8 z()Z)F2KkGAjh}r^yj?NxQ`$u7sZt?7Ab?EHp5n-aYq|?>$4&*~f{an?KgH_eJX8iL*#j~X2_4Yd^?sQzYVGZa56y+jZ9kKj6$ z>CGEm@HvR=9Pw2lchNddfAZj|44P499@xJblQ3klMGGAWW*8X$X=gCyCEk{7IeFXQ z#=opBM&6{3de3*K00tGmzk}gEJIVg{tACX>**{PL{hv2W1KioB`VMPGT?@(jaWe_a zRp6L5eEmM30zu}W??zKVmASae#FX(|XHMLQY7RB(sm~q|@g9~7?{bd*lGY*1kMGFp z&_k9Xjql!r4{rI%1cc4(A-dX=r>J@b5ZgVWIO(i^%1Cm2nusZ47E8$9Z_zht-ao1b zt*?DqdAqQGIJctwedqhp2IfPqIqJxAkv_UPeI&~l^TC^*T~^-NG?KLw1C<7z-6?Fx z8phTGnhqtNICrX{t=TVYGJLHs$^qO*xUw_EuIr{bi})?rXZ(~n z{dzs$1G}qEQVeRM*J(4{e}P#7v9|!Efk;6y~2+S&TW%Y`Fh|8fQVSW$7<%^Z4&kK3# zajT9UdLrd3a!@Rv6ghT?!d{Q<^p`pBCh@qVvx+AeyoNE=>8xCOAyWhKJEgSazkF&U zz7x&1)@SJPG5mRU%&4V)?F`IbA0CI9ieKYa(6{8ch_4`q)~4w*UqvaMQrw3hoA!=qa$m6VX(Q%hChE_UnsO_*J#0 zM;L6Ihs+rviJpuIY(|i(Z2~}S-PK0GKw17+bNwi%-PsR8_`OD&lm!NiF!zzpt;?lC z*wy#8Xwdr2lU6Kw(pA>#5!iPBnWqHGNA{a;>C2~0POP&D;T!@5+Iq9RxeB8x{RedHL2#d;mNkEeK|`l}A&2OT25@(`fWCl>mG zqosq4IrX}ZpGE7Por~lhlwBq)o^l|n=yK}WxI2QDMh?}~iW+6KYph(!M@qi_ znyB_k{qD1SA1myd3LWoHpQPc@{LR(N{LT6zSoP_kLdiI35;L>D!VR zfcaL4*+;-W|G3?u`Grxu_({bM$=it!f1}EqNE0~x3csQ@PMYg?nNCrTpa(XWJREil ziC-jo&(pCepUir9HU2~@{w1kMt7`kCxK({gVSVmvLz3pZ`kYR`eQ?p|?ve2pV*5m> z5GJq$CK7qbXgi|ixax{uGBRRxtfcM}7x9{y|0KFFYLu;&<)k7jQsyBrU}DO8;u>w` z!q)s9pxtFr&()xTdTnYH>QRz*fF5+zKmXbXbj%-GY_QCe4X=prpe^P3&`)pd+u5i|YjylC%8QI5>M z<=M#!{2*fR4Kh5eHCpbhs(Wn0T#P)=D>W=5;w~fNwiQa2ld6Qtb6;<;?j1*wlo<+T z>N4XHKZsqf;dY@cu(wB#U+lZce~}5(zG`VlfOH8)KCH)RB;z`S1^oTz+t}TxK{U-) za=VZ#(qg05^7xyffb(UU9dS6zXo6-dv7O^iH6u5%u<%(sy+%eE=dOO7iSKSlCCXC*tks9N*;ZXQ4`t+qhk(2yRB;gdl9wNEeur7uR(v7CV`7coz)!4!XC zG^%UnJ^4zj9d?DO{o50`O8C9lj@tEfG#_!M^^on;?7cM>s}n>dMP3hBbAw8Ov7L8X zARMXWQlkHzN`ZX*rrDE7@zVCL*ts%E+0OU|7_t2;l&emDb0X9O!Flz@IL zxyW25;uGA3o)n%K8Q-PUSzf^Hc!7(CSAuo>XxDF6H%v2;JX*EhGiaVo#7f0kqusue zLEG-GN5G&H=H8d2+_+|#1?WhkW~+Kg;FeY3OI#WCAsH?OmD&Clg{J-FGf+xM^<9Xw zdYUxn#mwt8Fwl`t;*d2SJ+fT~31-4$eocobA4{}6^M&ux5k*vZ=bMj*8&1c&*V`qu zv78S-WYRyemh*?`S*N_QgH)sh^fzp#-1Zo(sg+QMyng6zhsM&;#xx#2LW&49Ey-T6x zUbj?oh_`mC6ifEu8lggZ;J;RWcy(MwR@0rb{+J+pF-TlOU-6XMj&kp%JoxF}^L(0u zYO4CEYsYe7BjR~d-KTgpSx-GKRd@&QL_n*7wsP***yYmc<4GAjrCE%Ds54H9W{kiY ze^_<-a7&_q9V0{5O$V8vs*cBCYk!1^LHm-HX*tCAR5-^iDl+v>YR*+pgqXSv$7%$p zcxzhuxvSpR`I{G;g6Exs1$NT-g8+?B&hUL%Cm=B!75xS*-GM*D9?!9ep$3eH`&!csQ!YGg5hLH^aazEaGLEQc(7&Wqs7ZwjroRwuN zIV*PUWfBVq^Z>{)nE3-ikSrg5t;t#~exb_k7N;t64Uy1Q{jsyyiBUs02^L3h(oJf# z-Fdk3ZQ=C6E$TM`UI|YMf(ni*p#~C<3G@B5NWxVW6^x0@BAmm!AoKfwBoD8IGA3Kg zB4!S#5-~lMdmeS)8I0cQg=jAh%BX&;BH80oM9B71+s(@&8(YagS~yMC#YHDgJ}ost z65d^eBkXaPTfyjaUCa*{ztag+W#qgVtSn;?1v**j_Ks(i!=!B716a%%jP3!16$-l| zW@;;#r3q6M%~H`cWOi0o3TyUe4m}gPH%%Xe)q`2Pp8JA_w`r#gK%RQ&kAw!Ud^Y7 zm!dz72^t?kJ7c`Zu*h1~PY+`0fk1X#Xu zpw!Kx#W%EwqW7&p0-kxv8*7rVgL%+o+>Y%c;Cc7)s*dZHi5FGvBHeGEkO(co$V?&% z%Y0Zk(LB-Cx$i`y-Iwh)m81uzZ-JXrOnK`HYI1y6fRr9pS}i8s zKXy@-8CyHFRc`ZhhRNv4Z@h?Vuli4TF*YV!nqQ9~aN~SoAhkA z)v0XGgx`P>;6>~z_1=y+m^HQ%$#(a8Gd;fO_f5FO z*8w|2$0Bq0HqkQX4v$6^5u+UJhPI|p+w7N##*pms@N~=6`D1c!n|zxg>yu9OWmi0O z({#mK+4i-KiLSW{bA^^L5a!3XSXLJ0ZCIyJAF2R5VA+!b_p)>p@3DHsPoX|lbtI{> zBE3CB#o!4V*H>5jVtEOKt%>mGjruxJaW<$ai4{gWRvq4H4nCaBAIJ3^Xr)a3DSlh%W(jCe;_8ZD90@H2o<(8Vd={N}&eNDcR_} z^hpU^ujp%!O-Vx3qE3C4<>~d-`js(R@qYy)Jq&P5;%w> zGb|aI%yH-jl+1FtZA_-EIy{zx7gsf9pG?9FnR~4_ECN7_{@xnBxkSRq)Xewn{dieM zV1`+H6$Mq$Pmrzm*~qj>($jXn7x=I|KRVl$ULp2hKdijLT6FiPXdpLewwX(&;+eye zD1N(D=Wg3+F<0{3_Oe#Q3js?I4s=Nzl2BhDw*>}_0BjDhl_tXCu>X|#Q#k^N0T~!{v<+@oXg!MfHvmWA AT>t<8 literal 0 HcmV?d00001 diff --git a/kubernetes-vault/README.md b/kubernetes-vault/README.md new file mode 100644 index 0000000..b6b4318 --- /dev/null +++ b/kubernetes-vault/README.md @@ -0,0 +1,122 @@ +## ДЗ#11 Хранилище секретов для приложения. Vault. + +### Задания: +- Данное задание будет выполняться в managed k8s в Yandex cloud +- Разверните managed Kubernetes cluster в Yandex cloud любым удобным вам способом. Создайте 3 ноды для кластера +- В namespace consul установите consul из helm-чарта https://github.com/hashicorp/consul-k8s.git с параметрами 3 реплики для сервера. Приложите команду установки чарта и файл с переменными к результатам ДЗ. +- В namespace vault установите hashicorp vault из helm-чарта https://github.com/hashicorp/vault-helm.git + - Сконфигурируйте установку для использования ранее установленного consul в HA режиме + - Приложите команду установки чарта и файл с переменными к результатам ДЗ. +- Выполните инициализацию vault и распечатайте с помощью полученного unseal key все поды хранилища +- Создайте хранилище секретов otus/ с Secret Engine KV, а в нем секрет otus/cred, содержащий username='otus' password='asajkjkahs’ +- В namespace vault создайте serviceAccount с именем vault-auth и ClusterRoleBinding для него с ролью system:auth-delegator. Приложите получившиеся манифесты к результатам ДЗ +- В Vault включите авторизацию auth/kubernetes и сконфигурируйте ее используя токен и сертификат ранее созданного ServiceAccount +- Создайте и примените политику otus-policy для секретов /otus/cred с capabilities = [“read”, “list”]. Файл .hcl с политикой приложите к результатам ДЗ +- Создайте роль auth/kubernetes/role/otus в vault с использованием ServiceAccount vault-auth из namespace Vault и политикой otus-policy +- Установите External Secrets Operator из helm-чарта в namespace vault. Команду установки чарта и файл с переменными, если вы их используете приложите к результатам ДЗ +- Создайте и примените манифест crd объекта SecretStore в namespace vault, сконфигурированный для доступа к KV секретам Vault с использованием ранее созданной роли otus и сервис аккаунта vault-auth. Убедитесь, что созданный SecretStore успешно подключился к vault. Получившийся манифест приложите к результатам ДЗ. +- Создайте и примените манифест crd объекта ExternalSecret с следующими параметрами: + - ns – vault + - SecretStore – созданный на прошлом шаге + - Target.name = otus-cred + - Получает значения KV секрета /otus/cred из vault и отображает их в два ключа – username и password соответственно +- Убедитесь, что после применения ExternalSecret будет создан Secret в ns vault с именем otus-cred и хранящий в себе 2 ключа username и password, со значениями, которые были сохранены ранее в vault. Добавьте манифест объекта ExternalSecret к результатам ДЗ. + +### Запуск +- Создать в yc необходимые ресурсы согласно описанию (Я это сделал в прошлом ДЗ) +- helm install --createnamespace --namespace consul consul consul +- helm install --createnamespace --namespace vault vault vault +- helm install --namespace vault external-secrets external-secrets + +### Описание решения +Для разворачивания consul я использовал репозитории hashicrop, установил количество реплик values.yaml: +```yaml +# consul +server: + replicas: 3 +``` +Для vault аналогично, вкелючил ha режим и установил storage consul: +```yaml +... + ha: + enabled: true + config: | + ui = true + +... + storage "consul" { + path = "vault" + address = "consul-consul-server.consul.svc.cluster.local:8500" + } +``` +Далее многие команды будут выполняться внутри пода vault: +```sh +kubectl exec --namespace vault -ti vault-2 -- vault operator init +``` +Эта команда отдаст ключи и root токен необходымые для распечатывания контейнеров: +```sh +Unseal Key 1: S2p18bRj8ZIBnuPvk+RCcWiunboTjkkbO**** +Unseal Key 2: 8FQA90iN9KVpQMKiyDNwhIhNUVwd/0y/6**** +Unseal Key 3: KS+ItQn+hJR2s/iH1b9yhqyX4nFFXyzvWF**** +Unseal Key 4: AigrSESb7Mvv58JqLhmOAhdumDLTacNJq**** +Unseal Key 5: amUvB9+nXop4Kv4ggSFFi4tZhKwMNpuxs**** + +Initial Root Token: hvs.m793pcUPXb**** +``` +Далее с помощью команд и ключей unseal нужно распечатать все поды: +нужно следить за Seal Progress ввыводе и вводить ключи столько раз сколько потребуется +```sh +kubectl exec --namespace vault -ti vault-* -- vault operator unseal +# enter Unseal Key +kubectl exec --namespace vault -ti vault-* -- vault operator unseal +# enter Unseal Key +kubectl exec --namespace vault -ti vault-* -- vault operator unseal +# enter Unseal Key +... +``` +``` +Создайте хранилище секретов otus/ с Secret Engine KV, а в нем секрет otus/cred, содержащий username='otus' password='asajkjkahs’ +``` +Я сделал это через web-ui: +![alt text](../img/image17.png) +![alt text](../img/image18.png) + +Далее в файле vault-auth-sa.yaml создал serviceAccount с именем vault-auth и ClusterRoleBinding для него с ролью system:auth-delegator +Далее внутри pod vault-0 включил и настроил kubernetes авторизацию: +```sh +# kubectl exec --namespace vault -ti vault-0 -- sh +vault auth enable kubernetes +vault write auth/kubernetes/config \ +token_reviewer_jwt="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \ +kubernetes_host="https://$KUBERNETES_PORT_443_TCP_ADDR:443" \ +kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt +``` +Далее прописал политику для otus/cred и настроил роль: +```sh +# kubectl exec --namespace vault -ti vault-0 -- sh +vault policy write otus-policy - <=1.22.0-0' +name: consul +sources: +- https://github.com/hashicorp/consul +- https://github.com/hashicorp/consul-k8s +version: 1.5.3 diff --git a/kubernetes-vault/consul/README.md b/kubernetes-vault/consul/README.md new file mode 100644 index 0000000..d917af6 --- /dev/null +++ b/kubernetes-vault/consul/README.md @@ -0,0 +1,109 @@ +# Consul on Kubernetes Helm Chart + +--- + + **We're looking for feedback on how folks are using Consul on Kubernetes. Please fill out our brief [survey](https://hashicorp.sjc1.qualtrics.com/jfe/form/SV_4MANbw1BUku7YhL)!** + +## Overview + +This is the Official HashiCorp Helm chart for installing and configuring Consul on Kubernetes. This chart supports multiple use cases of Consul on Kubernetes, depending on the values provided. + +For full documentation on this Helm chart along with all the ways you can use Consul with Kubernetes, please see the Consul and Kubernetes documentation. + +> :warning: **Please note**: We take Consul's security and our users' trust very seriously. If +you believe you have found a security issue in Consul K8s, _please responsibly disclose_ +by contacting us at [security@hashicorp.com](mailto:security@hashicorp.com). + +## Features + + * [**Consul Service Mesh**](https://www.consul.io/docs/k8s/connect): + Run Consul Service Mesh on Kubernetes. This feature + injects Envoy sidecars and registers your Pods with Consul. + + * [**Catalog Sync**](https://www.consul.io/docs/k8s/service-sync): + Sync Consul services into first-class Kubernetes services and vice versa. + This enables Kubernetes to easily access external services and for + non-Kubernetes nodes to easily discover and access Kubernetes services. + +## Installation + +`consul-k8s` is distributed in multiple forms: + + * The recommended installation method is the official + [Consul Helm chart](https://github.com/hashicorp/consul-k8s/tree/main/charts/consul). This will + automatically configure the Consul and Kubernetes integration to run within + an existing Kubernetes cluster. + + * A [Docker image `hashicorp/consul-k8s-control-plane`](https://hub.docker.com/r/hashicorp/consul-k8s-control-plane) is available. This can be used to manually run `consul-k8s-control-plane` within a scheduled environment. + + * Consul K8s CLI, distributed as `consul-k8s`, can be used to install and uninstall Consul Kubernetes. See the [Consul K8s CLI Reference](https://www.consul.io/docs/k8s/k8s-cli) for more details on usage. + +### Prerequisites + +The following pre-requisites must be met before installing Consul on Kubernetes. + + * **Kubernetes 1.27.x - 1.30.x** - This represents the earliest versions of Kubernetes tested. + It is possible that this chart works with earlier versions, but it is + untested. + * Helm install + * **Helm 3.6+** for Helm based installs. + * Consul K8s CLI based install + * `kubectl` configured to authenticate to a Kubernetes cluster with a valid `kubeconfig` file. + * `brew`, `yum`, or `apt` package manager on your local machine + +### CLI + +The Consul K8s CLI is the easiest way to get up and running with Consul on Kubernetes. See [Install Consul on K8s CLI](https://developer.hashicorp.com/consul/docs/k8s/installation/install-cli#install-the-cli) for more details on installation, and refer to +[Consul on Kubernetes CLI Reference](https://developer.hashicorp.com/consul/docs/k8s/k8s-cli) for more details on subcommands and a list of all available flags +for each subcommand. + + + 1. Install the HashiCorp tap, which is a repository of all Homebrew packages for HashiCorp: + + ``` bash + brew tap hashicorp/tap + ``` + +2. Install the Consul K8s CLI with hashicorp/tap/consul formula. + + ``` bash + brew install hashicorp/tap/consul-k8s + ``` + +3. Issue the install subcommand to install Consul on Kubernetes: + + ``` bash + consul-k8s install + ``` + +### Helm + +The Helm chart is ideal for those who prefer to use Helm for automation for either the installation or upgrade of Consul on Kubernetes. The chart supports multiple use cases of Consul on Kubernetes, depending on the values provided. Detailed installation instructions for Consul on Kubernetes are found [here](https://www.consul.io/docs/k8s/installation/overview). + +1. Add the HashiCorp Helm repository: + + ``` bash + helm repo add hashicorp https://helm.releases.hashicorp.com + ``` + +2. Ensure you have access to the Consul Helm chart and you see the latest chart version listed. If you have previously added the + HashiCorp Helm repository, run `helm repo update`. + + ``` bash + helm search repo hashicorp/consul + ``` + +3. Now you're ready to install Consul! To install Consul with the default configuration using Helm 3.2 run the following command below. + This will create a `consul` Kubernetes namespace if not already present, and install Consul on the dedicated namespace. + + ``` bash + helm install consul hashicorp/consul --set global.name=consul --create-namespace -n consul + +Please see the many options supported in the `values.yaml` +file. These are also fully documented directly on the +[Consul website](https://www.consul.io/docs/platform/k8s/helm.html). + +## Tutorials + +You can find examples and complete tutorials on how to deploy Consul on +Kubernetes using Helm on the [HashiCorp Learn website](https://learn.hashicorp.com/collections/consul/kubernetes). diff --git a/kubernetes-vault/consul/addons/gen.sh b/kubernetes-vault/consul/addons/gen.sh new file mode 100644 index 0000000..1d03390 --- /dev/null +++ b/kubernetes-vault/consul/addons/gen.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + + +WD=$(dirname "$0") +WD=$(cd "$WD"; pwd) + +set -eux + +TEMPLATES="${WD}/../templates" +DASHBOARDS="${WD}/dashboards" +TMP=$(mktemp -d) + +# create Prometheus template +helm template prometheus prometheus \ + --repo https://prometheus-community.github.io/helm-charts \ + --namespace "replace-me-namespace" \ + --version 13.2.1 \ + -f "${WD}/values/prometheus.yaml" \ + > "${TEMPLATES}/prometheus.yaml" + +# Find and replace `replace-me-namespace` with `{{ .Release.Namespace }}` in Prometheus template. +sed -i'.orig' 's/replace-me-namespace/{{ .Release.Namespace }}/g' "${TEMPLATES}/prometheus.yaml" +# Add a comment to the top of the template file mentioning that the file is auto-generated. +sed -i'.orig' '1i\ +# This file is auto-generated, see addons/gen.sh +' "${TEMPLATES}/prometheus.yaml" +# Add `{{- if .Values.prometheus.enabled }} to the top of the Prometheus template to ensure it is only templated when enabled. +sed -i'.orig' '1i\ +{{- if .Values.prometheus.enabled }} +' "${TEMPLATES}/prometheus.yaml" +# Add `{{- end }} to the bottom of the Prometheus template to ensure it is only templated when enabled (closes the `if` statement). +sed -i'.orig' -e '$a\ +{{- end }}' "${TEMPLATES}/prometheus.yaml" +# Remove the `prometheus.yaml.orig` file that is created as a side-effect of the `sed` command on OS X. +rm "${TEMPLATES}/prometheus.yaml.orig" \ No newline at end of file diff --git a/kubernetes-vault/consul/addons/values/prometheus.yaml b/kubernetes-vault/consul/addons/values/prometheus.yaml new file mode 100644 index 0000000..1f90636 --- /dev/null +++ b/kubernetes-vault/consul/addons/values/prometheus.yaml @@ -0,0 +1,21 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +# Disable non-essential components +alertmanager: + enabled: false +pushgateway: + enabled: false +kubeStateMetrics: + enabled: false +nodeExporter: + enabled: false +server: + podAnnotations: + "consul.hashicorp.com/connect-inject": "false" + persistentVolume: + enabled: false + readinessProbeInitialDelay: 0 + # Speed up scraping a bit from the default + global: + scrape_interval: 15s diff --git a/kubernetes-vault/consul/assets/icon.png b/kubernetes-vault/consul/assets/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..0798b2445de59405c89614338a3276bfb36d832f GIT binary patch literal 7981 zcmaKRWlS7Ew>FDwad)@HU0RAS?y$I(;!@mQyDjcer1)ZsyE_zzMT!W|PYye4MuFuM(9h1=2Pt0+J6Gc^x zPl)vVNb$Q^W4_$090&4mc9favc4lPpY)*FeNIr_S6rGN00T#Ah!Whwjif_R2R4^(r z_g?qi(7jQ>MAH8qG>Vp-hHRqME)>ms!+m`&;&!KPB&(717wOaY3XB>ooP95ZQS|~K zG7<^wh+}z3`j6)v)5Dcy9%lXa+V5BPzd&(3tDGohV|}k_)$^qqEdSY%HeeXT82ks4ITC|Rb=FKOnL}heG+wJ998Zf5c z;z9KD>o!8DYG={Cbrqb;pjdi^DAUd;kzZS<2cQSGR*I9TnZX?AdD7fKpPiv1#(3+d z^y5pSBp;`->}s9gN>q5BR;lIh0ip*x!;}w9nPjoz0))m^!X%wyygqwF17)jf1ApzL zPd~iJ6vxvL-oXHV{++jBY=&>3<5^p?apxOeAjb;Px`v?T2VVY4N{P4DizNukVRVdc zQ8Nb-aP5j$MOPk>AH8|c*uv}jC;kSy7B4+akRo5`j+&M)-4bz6F1zW`3nh}iI_|!; zp~Z90cK#CCJdjWjD@@{mPdhi5KepX3kW%%9NOTghV3Q*6-&)*lG}Q={Wd33^u*;MB z1FZ&>S{v1N?u@CA^*)80%@DU}^GM$l=zq_~q(k@1))#3EeP;nsNpUrhg%v<+Iy_I# zxjOqHMyIl#ljK8KPjAe^FniFM(@E}qWst|_>dWrWtCwCv*KM3!qK?0QUY84geE*93 z?7TD*B}+DcahZ0xshZfCR#$q3qAZfxX$pFJb#H%2{>M7`8v_I7g)nmA-gKn?j35)m zO+QQ``2L{2TI$e%ENxpFr*7jgVVtz1Z-i_9kw@GjEmtA9Wq>q9y8*vbdcGhAnGt{{ z-n<)9A`u$6htuRRSrYtlAaCHgvgM`K+`s1l=PrK=7z7vk{S#Np=R0iS>UvJfZjFH` zaJ|l+q@7G$)(H@W_GkdWX~W(BF=HlLBa;TfQLyJm7G}w%t3LSw<%PxCT102Q9bDz} z1L*qb5-sJ#)SA$A>6Y^W$kDD%zAN*q!<1}^(?>2EB)7kCOsW->|CU+0hrUGoRh$-1 zb=--O2zVRlD}TxzPD)e{YJ!Scq=iWz&ZDk_a5qreu_za=aa@Qi8z9<`KjsHEIH6V{>65Qx4x%TfxO|kh|76~|r35W_ zl$#yvHv1QFca>!FvKX$X=Q(2#XWi#tM)!?8S%*J=zuR<3F*iRS%Ul}Hvv7f@(JiqX zsz(Ii<42K44ZX(+pV1?s6M6#Zfie>D9sSL@q~sOtX-(7==p?CF+0l8tGl%dFz%T%3 zE`-2rUxC@5i_D{U!%DHd{E=MRg z*RcsQi?K!2n+Xx)GkBhece)Xe+nnbYX|o9QcpRb9bTFq|8e><8MnNTx?KYAHf)I_^`d)XyqAQRb=^ohDmWzT zl6oAgYTFR@SYJQkO=iULksy61<`TqJyBmd>3-LL2V>OL*t#qqghezSx(?xP{g zTS?^umeGax6|sYY;z-IbytKzLB@mG5 zqc*PfC&PX0>N&(eHeD%YqaXztdwdy9=`Xd-oU~l!m>ZoQzjff4dLP(&6=5a64-0-j z_75Q0ee#fwAPLk8zDZjJorIWq) z+)F{D5ct#!j-}1k1NoTy%+14W6~uOG31?7q;G=ywT^;r$5a;oh>LK8y^SAk@r;YsD z#5SAy0)ko~cN`p7Zz;SaX{)t z{~|%)&+SAw!%C;$Wn-Dg`DXe8r%|v4yEFW&Fh7yzM8=B>FOI4UHjtfJ>S@So%ymm~ z2EMV~-7Y)3mE&HrN^abSRFnqLU%M~5Z?h)=*R{NrANd?u_Rn#B{)I&hlgPPb-DlTN zrf0Ws^s>T+FVdcuoCL8(xuA>xJMR<-6&C+RZmM9-?ywQ9;a;9={Bhra*cHB)bh&2D zFvWybU)i$JNvG68F)`%(2E3!cQNox6!E*1ct2{NQL!mu~0`=+R#U4g1olAFWM3cSf z+n+j4Ji!z@=W`aaEBt%EjrH6`U?d?IT{vwozq(&&Ub(|?9cQBSxrvz4&3(L;pCYtK zAnCg76Vn>bfez;1Z{0uQN&Szu%S1bOWsSyBctjIb%szs(E$H)TTO5Cr6oKK}s8X(n z8l0Gi?8@i4GjSH>ClD56Phk1Igh6oX7Gk;ODgG5Q9Rg{wS(XVZjrxo7qPO{3pab?{ z%slB~^w|YTswv}>ANMQ|<)@$BzC*%EmWT=7_`kMB%YF*EO3VmYs5o!MZr9r<2v#DF zeYJy@N=o53%l#Nv{L%LhH+4v&D0f8d?WM|3)3V}y4pprfYILX;T&InUODW%*jMcke zvMxJCq(1=~olJ?UiP0CkMJw&j?nRK+o)&BkQa-ZWQ`3py2jA!pGBuQEZ-0ZDiw4RV zud;iWsQZQ2-3=Tzd@gD-HhkvAHt68^_Ju?+@Xsn#p}w5=O4QfyvMScQ>po;6fMy|l z63~%NOy@Kl^5j&QFPD8{)rm}vZg`Vu!;ei-dp|E=PUYh_|MfC;CXtPo{UkfPL{05o z8IMr~_d!tL5H04Q*ZZ0AmrGkLy1$vGVJdy3{#OYzSI02oqb9_=;t{jpa5e1N@ZM|V!l26;Z}N*V zdD|O#{szd~cb^O`%k0Ao?7EFKo2~zN0D&y!)ugrT48dWaouN>0BW4V|&2;1m<@CC; zyyAAyeExbcfO2_4(}*-sEKHA4h|^3!a@;l^F z3ajr=^+UGUGN3Zf7`wTaIM{xO16&WwTASeDt1%i-aO9qK{c%f*jWIW)Vg1>N((XaO zyx*4hxKg%B0al@hXid!=;&1;v>T6TWwr9!faA|95RKIGZ%= zGt0`)uW#A8ah9#~rV40YJ`>K=zh3mMRVU|9<%Ybce=E7@Z#0fxWwiWVw^fY_e%J12KS0LhEzQz7oD#hwdRKw6W>>w7&*-%Bria3K9wK{%nsexvu z`o222VzDxeqq9Hv`2C>l!-SQ=(cxC8kb1P<{9xqfXD;pP*7bzB-)u0vYWX>00!T1M zG_TqR+0?mGGrb(^#R$~ef3j5U4fKDG^o^K$MQh<4hEQ0Iv`#TfVcKf3i;&?8!12rN zQhEWRRv4@?zl+FFHG)b(x505{p`^X?$MywJP?Wk5R&?vmL25Toze#pBlD?K)m(re0 zCVvu(a(L!fhA4<)w^pJd7w7C{EsHLP_LmV zSxK}Rw;~~sEvMf(Gzrw6A*4LXdVOJSX!6zCSu&DJ%hS}c4!QnSb4uE3e#9`Y-;aMT zF|vI3bV0g!5y{ZWM71fX}#bdUE%{h%(gyh zk_t}f{DeA$6yrW$g!Dp)VMlv_B9!OWJDw8WUVi@xkf2%}w`Llw%QV;3+YaMaD+J1> zE(dION`N>^Jo2f`@sG0%R`-wJfcaEJTXx7Uxwxp`Pvgg?`jdS**k86=uc`a<Ds+c3W1>!4Bhi1p<~wIHgRy5Jjx+DWs>0}3 zisj@NH9ci8L|tZjS2yx{3>~<2w?p-~C6(T?6G8BkN2^P+J|~;jZDMh)@Al30eyAlY zTR*QCCMd0MiHZAovl%W#V_sLYF}E-aCA}#N6Ivr?gJ(Mr#Tk*(SNtP&0hVVv%Wu zFd1?$%&6IvBoH?%c?H25Utw-mNz~d0)+nc_N9h zhBcv3@8Jj%%)YqhnAcrM7g@Su%GzF8VGTH8=LGvahT}fldQBaPSu~L#$==Y4qFo52 zUF*tOf7CHa)~?M;ne($;%@L(hlbaQdPtSDKII^3bh(^NLvl?h1p+7gk`j=^<{9CV{ zHJ}sq`FOgtmr&UCCB>C7@ACOz#Xmqt0+ADb^>$MPV8AL_i9jAEizUG!2~^hJLdL{= zqJM|98PwUI5GyNT(FEiDQIqEf${;grc)q)6LZ1!2J@#|DuL&@JV}9G!_*iH2xL-4f zvRALr3A5_PgF2)-C&ZR`Eh8-}Ek z4!qxrz#V>Zssh*jqGf#jEMqpea6VF8zI9%0bgb=aW~2+<+K!bB|@O*Cn3{Wr9_=_lZ&Tp>xZ+FbztNex;bjo&uhSC+&T-)dOujx|J3` zS!HVyt~k1h@~PDi)1d1`iZ5?a1^=n|-mKX2sTV+38nT+Bkn~*$68DH)m@_Baz5H|P zWnILOdCse70=jmyY?n|B9_<=B@JE796x-%0WFTfN2T2HA$9Z*=+zgh0^I zL@oA|GEpm}m?ybuf!DlNMw!rfC#I+huiD-4$Y?YgUpfd5;6rhF=**4kHU1HG!7wfT zIW_E}c(Kx8B4GW@7lZL&OAWwDZA$?w4s8zBLL9{ex_3(7DpQ2YQ6i~u{GCCkh7E%d z&^Ar#x90Q+VS?{y#`ys%IwvKyh1=Y18DS`9%vw>_AikKyG!j%?(Ku`A=<&+|hPK1f zoKVWPqz#GqGy$b1rTLMREoOOwF-7gP;&^%E(O(h2aLw3O=A@+|q&#p@l3;ar>57{q z6Kk+)wqTqflqsJ1D}kg;Rq%G?MO?obT2&l^eml<4B}aA7v3_Cca99PXD^GaCZ2-sV zd$t2@LBz>>RO4EGi=e0Tk<#LnBCA%3cs(G@Ea0T6G&P7I$}lv_KBYIgS12sXj`3xX zF+nmpDlWS>c{Q!Hi%)E?>wWUZB!G(SA8lNk%15<28U zlsj@IJ;V0~ET5!1Y{^_F!5X)#mhtY&M2`NP7y~$;2UB+7gzY8}z*NyPk@UluWcdzN zRq9359{U0lty13r=kGYEiv z;>7O(lQ$MVJ}oS1?#StDAaxvsSTK=qTDok~DP7tR-=l?!RuXYs>|tYRvr8pbjOLPlqEXTa#glhaK$xs-e2B1xry z!LXiWJw)hoRX6*&FQ1kj-|XM~bX|%^hWYZ;D@{WBx9$<1@VL?Lid?rD|5-;~vvq>_ zXjk__g}mz@RU`Llf|ilL`XVUFP0dq}YoB6QodNuN5kGgCaMA;)lE)b0bxQsYv~6O)d+i{(%7{9I7z*uX+9( z6LpJ1;nJX+UK&1r(ML(I%>E?}kuSfnuj&Az0V^f%1 zYv4*izmb7mX{;%JhN6PS*OM|80I(b349Wi7utS&y0PzoV6TpSmY&U4tu;hnPx`R9X znUa1ms#Pq{9v$?}wR-kbwNb?h;hW{@o8jXc-|+MOMa{t%Mcq++hw`_?OiNCayeXJz zC(_+8G;N_1S8=WjhKS{Q_s|9=*NHbS-Q$k1_^O>isw4Z|Tkwz@$th!H;IKX-rJN44 zZ;|Ye5fT*_b(a5rCJFP#P9HDsuu@~G_?&viVv>`?7Fl)r;IWtm$$UB@xRoc{F@_xj z-0FBZ`M3*Y`2;jX$@diYaM@)lvDF_lq82DzVWKMdrukXs%gmsN8gHe|m+ITi5Gng* ziy62htqvAyXJUUCllVc^l%J1NRB&v|X)(IXgE$ZQQgSiI8g<2U z=BP@FsW`F5Y*pZBju-OjIPT^`*);9!N-f%Xn1ln(WX29vSEKH9DS99oC@XE8>(}`_ z=Gf6w!8*NzsyB`*ydZ90omwvBuZk(X)15&3H4;FH;e{&yc2QPa~x9H_8HKo+KH%4;Hz$^eyBPn@4qiJVxr z`=Oq)OWXl$yC85~%CufXuQErnqs_DgX4@QP+lSjuQZ!(m%H)YsJnALuC1ddX4k`a(VjL6G}Ir!1u(B1SV>*{zg$&ZZCOr zF=>VYdvOG0_DQv|KL=j2yvm@zq3rLi1mKVv`L!eTSIgfKqe65-LH?sAM2zH{eP*}R}HS?y`N5+5&x5v#6@*Ti8flzE;^nVi=hJQ){e7}=Q= zRh_{lmR_1;t{}zxGU$h`L&9Q7w zvSLDfOM1i``K++vn*c-TU+O8Aiyu28OyAf%cRl}qH}`*u+{LmNv{QR1$3$A8$!ohB OK}lX+u13Zp{Qm*> alphanumeric characters + => '-', '_' or '.' + => must start and end with an alphanumeric character + (e.g. 'MyValue', or 'my_value', or '12345', regex used for validation is + '(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?') + +Usage: {{ template "consul.versionInfo" }} +*/}} +{{- define "consul.versionInfo" -}} +{{- $imageVersion := regexSplit ":" .Values.global.image -1 }} +{{- $versionInfo := printf "%s" (index $imageVersion 1 ) | trimSuffix "\"" }} +{{- $sanitizedVersion := "" }} +{{- $pattern := "^([A-Za-z0-9][-A-Za-z0-9_.]*[A-Za-z0-9])?$" }} +{{- if not (regexMatch $pattern $versionInfo) -}} + {{- $sanitizedVersion = regexReplaceAll "[^A-Za-z0-9-_.]|sha256" $versionInfo "" }} + {{- $sanitizedVersion = printf "%s" (trimSuffix "-" (trimPrefix "-" $sanitizedVersion)) -}} +{{- else }} + {{- $sanitizedVersion = $versionInfo }} +{{- end -}} +{{- printf "%s" $sanitizedVersion | trunc 63 | quote }} +{{- end -}} + +{{/* +Sets the imagePullPolicy for all Consul images (consul, consul-dataplane, consul-k8s, consul-telemetry-collector) +Valid values are: + IfNotPresent + Always + Never + In the case of empty, see https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy for details + +Usage: {{ template "consul.imagePullPolicy" . }} TODO: melisa should we name this differently ? +*/}} +{{- define "consul.imagePullPolicy" -}} +{{ if or (eq .Values.global.imagePullPolicy "IfNotPresent") (eq .Values.global.imagePullPolicy "Always") (eq .Values.global.imagePullPolicy "Never")}}imagePullPolicy: {{ .Values.global.imagePullPolicy }} +{{ else if eq .Values.global.imagePullPolicy "" }} +{{ else }} +{{fail "imagePullPolicy can only be IfNotPresent, Always, Never, or empty" }} +{{ end }} +{{- end -}} \ No newline at end of file diff --git a/kubernetes-vault/consul/templates/auth-method-clusterrole.yaml b/kubernetes-vault/consul/templates/auth-method-clusterrole.yaml new file mode 100644 index 0000000..6b8f2c5 --- /dev/null +++ b/kubernetes-vault/consul/templates/auth-method-clusterrole.yaml @@ -0,0 +1,18 @@ +{{- if .Values.global.acls.manageSystemACLs }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "consul.fullname" . }}-auth-method + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: auth-method +rules: +- apiGroups: [ "" ] + resources: + - serviceaccounts + verbs: + - get +{{- end }} diff --git a/kubernetes-vault/consul/templates/auth-method-clusterrolebinding.yaml b/kubernetes-vault/consul/templates/auth-method-clusterrolebinding.yaml new file mode 100644 index 0000000..9bd6c64 --- /dev/null +++ b/kubernetes-vault/consul/templates/auth-method-clusterrolebinding.yaml @@ -0,0 +1,39 @@ +{{- if .Values.global.acls.manageSystemACLs }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "consul.fullname" . }}-authdelegator + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: auth-method +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: "system:auth-delegator" +subjects: +- kind: ServiceAccount + name: {{ template "consul.fullname" . }}-auth-method + namespace: {{ .Release.Namespace }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "consul.fullname" . }}-auth-method + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: auth-method +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "consul.fullname" . }}-auth-method +subjects: +- kind: ServiceAccount + name: {{ template "consul.fullname" . }}-auth-method + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/auth-method-secret.yaml b/kubernetes-vault/consul/templates/auth-method-secret.yaml new file mode 100644 index 0000000..af0aeb4 --- /dev/null +++ b/kubernetes-vault/consul/templates/auth-method-secret.yaml @@ -0,0 +1,16 @@ +{{- if .Values.global.acls.manageSystemACLs }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "consul.fullname" . }}-auth-method + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: auth-method + annotations: + kubernetes.io/service-account.name: {{ template "consul.fullname" . }}-auth-method +type: kubernetes.io/service-account-token +{{- end }} diff --git a/kubernetes-vault/consul/templates/auth-method-serviceaccount.yaml b/kubernetes-vault/consul/templates/auth-method-serviceaccount.yaml new file mode 100644 index 0000000..098339b --- /dev/null +++ b/kubernetes-vault/consul/templates/auth-method-serviceaccount.yaml @@ -0,0 +1,19 @@ +{{- if .Values.global.acls.manageSystemACLs }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "consul.fullname" . }}-auth-method + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: auth-method +{{- with .Values.global.imagePullSecrets }} +imagePullSecrets: +{{- range . }} +- name: {{ .name }} +{{- end }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/client-config-configmap.yaml b/kubernetes-vault/consul/templates/client-config-configmap.yaml new file mode 100644 index 0000000..cab2c7c --- /dev/null +++ b/kubernetes-vault/consul/templates/client-config-configmap.yaml @@ -0,0 +1,40 @@ +{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} +# ConfigMap with extra configuration specified directly to the chart +# for client agents only. +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "consul.fullname" . }}-client-config + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: client +data: + client.json: |- + { + {{- if and .Values.global.secretsBackend.vault.enabled }} + "auto_reload_config": true + {{- end }} + } + log-level.json: |- + { + {{- if .Values.client.logLevel }} + "log_level": "{{ .Values.client.logLevel | upper }}" + {{- end }} + } + central-config.json: |- + { + "enable_central_service_config": true + } + {{- if .Values.connectInject.enabled }} + {{/* We set check_update_interval to 0s so that check output is immediately viewable + in the UI. */}} + config.json: |- + { + "check_update_interval": "0s" + } + {{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/client-daemonset.yaml b/kubernetes-vault/consul/templates/client-daemonset.yaml new file mode 100644 index 0000000..9c60738 --- /dev/null +++ b/kubernetes-vault/consul/templates/client-daemonset.yaml @@ -0,0 +1,611 @@ +{{- if .Values.global.imageK8s }}{{ fail "global.imageK8s is not a valid key, use global.imageK8S (note the capital 'S')" }}{{ end -}} +{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} +{{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} +{{- if (and .Values.global.adminPartitions.enabled $serverEnabled (ne .Values.global.adminPartitions.name "default"))}}{{ fail "global.adminPartitions.name has to be \"default\" in the server cluster" }}{{ end -}} +{{- if (and (not .Values.global.secretsBackend.vault.consulClientRole) .Values.global.secretsBackend.vault.enabled) }}{{ fail "global.secretsBackend.vault.consulClientRole must be provided if global.secretsBackend.vault.enabled=true." }}{{ end -}} +{{- if (and (and .Values.global.secretsBackend.vault.enabled .Values.global.tls.enabled) (not .Values.global.tls.caCert.secretName)) }}{{ fail "global.tls.caCert.secretName must be provided if global.tls.enabled=true and global.secretsBackend.vault.enabled=true." }}{{ end -}} +{{- if (and (and .Values.global.secretsBackend.vault.enabled .Values.global.tls.enabled) (not .Values.global.tls.enableAutoEncrypt)) }}{{ fail "global.tls.enableAutoEncrypt must be true if global.secretsBackend.vault.enabled=true and global.tls.enabled=true" }}{{ end -}} +{{- if (and (and .Values.global.secretsBackend.vault.enabled .Values.global.tls.enabled) (not .Values.global.secretsBackend.vault.consulCARole)) }}{{ fail "global.secretsBackend.vault.consulCARole must be provided if global.secretsBackend.vault.enabled=true and global.tls.enabled=true" }}{{ end -}} +{{- if and .Values.global.federation.enabled .Values.global.adminPartitions.enabled }}{{ fail "If global.federation.enabled is true, global.adminPartitions.enabled must be false because they are mutually exclusive" }}{{ end }} +{{- if (and .Values.global.enterpriseLicense.secretName (not .Values.global.enterpriseLicense.secretKey)) }}{{fail "enterpriseLicense.secretKey and secretName must both be specified." }}{{ end -}} +{{- if (and (not .Values.global.enterpriseLicense.secretName) .Values.global.enterpriseLicense.secretKey) }}{{fail "enterpriseLicense.secretKey and secretName must both be specified." }}{{ end -}} +{{- if and .Values.externalServers.enabled (not .Values.externalServers.hosts) }}{{ fail "externalServers.hosts must be set if externalServers.enabled is true" }}{{ end -}} +{{ template "consul.validateRequiredCloudSecretsExist" . }} +{{ template "consul.validateCloudSecretKeys" . }} +# DaemonSet to run the Consul clients on every node. +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ template "consul.fullname" . }}-client + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: client + {{- if .Values.global.extraLabels }} + {{- toYaml .Values.global.extraLabels | nindent 4 }} + {{- end }} +spec: + {{- if .Values.client.updateStrategy }} + updateStrategy: + {{ tpl .Values.client.updateStrategy . | nindent 4 | trim }} + {{- end }} + selector: + matchLabels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: client + hasDNS: "true" + template: + metadata: + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: client + hasDNS: "true" + {{- if .Values.client.extraLabels }} + {{- toYaml .Values.client.extraLabels | nindent 8 }} + {{- end }} + {{- if .Values.global.extraLabels }} + {{- toYaml .Values.global.extraLabels | nindent 8 }} + {{- end }} + annotations: + {{- if .Values.global.secretsBackend.vault.enabled }} + "vault.hashicorp.com/agent-inject": "true" + "vault.hashicorp.com/agent-init-first": "true" + "vault.hashicorp.com/role": "{{ .Values.global.secretsBackend.vault.consulClientRole }}" + {{- if and .Values.global.secretsBackend.vault.ca.secretName .Values.global.secretsBackend.vault.ca.secretKey }} + "vault.hashicorp.com/agent-extra-secret": "{{ .Values.global.secretsBackend.vault.ca.secretName }}" + "vault.hashicorp.com/ca-cert": "/vault/custom/{{ .Values.global.secretsBackend.vault.ca.secretKey }}" + {{- end }} + {{- if .Values.global.gossipEncryption.secretName }} + {{- with .Values.global.gossipEncryption }} + "vault.hashicorp.com/agent-inject-secret-gossip.txt": {{ .secretName }} + "vault.hashicorp.com/agent-inject-template-gossip.txt": {{ template "consul.vaultSecretTemplate" . }} + {{- end }} + {{- end }} + {{- if .Values.global.tls.enabled }} + "vault.hashicorp.com/agent-inject-secret-serverca.crt": {{ .Values.global.tls.caCert.secretName }} + "vault.hashicorp.com/agent-inject-template-serverca.crt": {{ template "consul.serverTLSCATemplate" . }} + {{- end }} + {{- if .Values.global.secretsBackend.vault.agentAnnotations }} + {{ tpl .Values.global.secretsBackend.vault.agentAnnotations . | nindent 8 | trim }} + {{- end }} + {{- if (and (.Values.global.secretsBackend.vault.vaultNamespace) (not (hasKey (default "" .Values.global.secretsBackend.vault.agentAnnotations | fromYaml) "vault.hashicorp.com/namespace")))}} + "vault.hashicorp.com/namespace": "{{ .Values.global.secretsBackend.vault.vaultNamespace }}" + {{- end }} + {{- if and .Values.global.enterpriseLicense.secretName (not .Values.global.acls.manageSystemACLs) }} + {{- with .Values.global.enterpriseLicense }} + "vault.hashicorp.com/agent-inject-secret-enterpriselicense.txt": "{{ .secretName }}" + "vault.hashicorp.com/agent-inject-template-enterpriselicense.txt": {{ template "consul.vaultSecretTemplate" . }} + {{- end }} + {{- end }} + {{- end }} + "consul.hashicorp.com/connect-inject": "false" + "consul.hashicorp.com/mesh-inject": "false" + "consul.hashicorp.com/config-checksum": {{ print (include (print $.Template.BasePath "/client-config-configmap.yaml") .) (include (print $.Template.BasePath "/client-tmp-extra-config-configmap.yaml") .) | sha256sum }} + {{- if .Values.client.annotations }} + {{- tpl .Values.client.annotations . | nindent 8 }} + {{- end }} + {{- if (and .Values.global.metrics.enabled .Values.global.metrics.enableAgentMetrics) }} + "prometheus.io/scrape": "true" + {{- if not (hasKey (default "" .Values.client.annotations | fromYaml) "prometheus.io/path")}} + "prometheus.io/path": "/v1/agent/metrics" + {{- end }} + "prometheus.io/port": "8500" + {{- end }} + spec: + {{- if .Values.client.affinity }} + affinity: + {{ tpl .Values.client.affinity . | nindent 8 | trim }} + {{- end }} + {{- if .Values.client.tolerations }} + tolerations: + {{ tpl .Values.client.tolerations . | nindent 8 | trim }} + {{- end }} + terminationGracePeriodSeconds: 10 + serviceAccountName: {{ template "consul.fullname" . }}-client + + {{- if not .Values.global.openshift.enabled }} + securityContext: + {{- toYaml .Values.client.securityContext | nindent 8 -}} + {{- end }} + + {{- if .Values.client.priorityClassName }} + priorityClassName: {{ .Values.client.priorityClassName | quote }} + {{- end }} + + {{- if .Values.client.dnsPolicy }} + dnsPolicy: {{ .Values.client.dnsPolicy }} + {{- end }} + + {{- if .Values.client.hostNetwork }} + hostNetwork: {{ .Values.client.hostNetwork }} + {{- end }} + + volumes: + - name: data + {{- if .Values.client.dataDirectoryHostPath }} + hostPath: + path: {{ .Values.client.dataDirectoryHostPath }} + type: DirectoryOrCreate + {{- else }} + emptyDir: {} + {{- end }} + - name: config + configMap: + name: {{ template "consul.fullname" . }}-client-config + - name: extra-config + emptyDir: {} + - name: consul-data + emptyDir: + medium: "Memory" + - name: tmp-extra-config + configMap: + name: {{ template "consul.fullname" . }}-client-tmp-extra-config + {{- if .Values.global.tls.enabled }} + {{- if not .Values.global.secretsBackend.vault.enabled }} + - name: consul-ca-cert + secret: + {{- if .Values.global.tls.caCert.secretName }} + secretName: {{ .Values.global.tls.caCert.secretName }} + {{- else }} + secretName: {{ template "consul.fullname" . }}-ca-cert + {{- end }} + items: + - key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }} + path: tls.crt + {{- end }} + {{- if (and (not .Values.global.secretsBackend.vault.enabled) (not .Values.global.tls.enableAutoEncrypt)) }} + - name: consul-ca-key + secret: + {{- if .Values.global.tls.caKey.secretName }} + secretName: {{ .Values.global.tls.caKey.secretName }} + {{- else }} + secretName: {{ template "consul.fullname" . }}-ca-key + {{- end }} + items: + - key: {{ default "tls.key" .Values.global.tls.caKey.secretKey }} + path: tls.key + - name: consul-client-cert + emptyDir: + # We're using tmpfs here so that + # client certs are not written to disk + medium: "Memory" + {{- end }} + {{- end }} + {{- range .Values.client.extraVolumes }} + - name: userconfig-{{ .name }} + {{ .type }}: + {{- if (eq .type "configMap") }} + name: {{ .name }} + {{- else if (eq .type "secret") }} + secretName: {{ .name }} + {{- end }} + {{- end }} + {{- if .Values.global.acls.manageSystemACLs }} + - name: aclconfig + emptyDir: {} + {{- else }} + {{- if (and .Values.global.enterpriseLicense.secretName .Values.global.enterpriseLicense.secretKey .Values.global.enterpriseLicense.enableLicenseAutoload (not .Values.global.secretsBackend.vault.enabled)) }} + - name: consul-license + secret: + secretName: {{ .Values.global.enterpriseLicense.secretName }} + {{- end }} + {{- end }} + containers: + - name: consul + image: "{{ default .Values.global.image .Values.client.image }}" + {{ template "consul.imagePullPolicy" . }} + {{- if .Values.global.acls.manageSystemACLs }} + lifecycle: + preStop: + exec: + command: + - "/bin/consul" + - "logout" + {{- end }} + env: + {{- if .Values.global.acls.manageSystemACLs }} + - name: CONSUL_HTTP_TOKEN_FILE + value: "/consul/login/acl-token" + {{- end }} + - name: ADVERTISE_IP + valueFrom: + fieldRef: + {{- if .Values.client.exposeGossipPorts }} + {{- /* Clients will be exposed on their node's hostPort for external-to-k8s communication, + so they need to advertise their host ip instead of their pod ip. */}} + fieldPath: status.hostIP + {{- else }} + fieldPath: status.podIP + {{- end }} + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: NODE + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: CONSUL_DISABLE_PERM_MGMT + value: "true" + {{- if (or .Values.global.gossipEncryption.autoGenerate (and .Values.global.gossipEncryption.secretName .Values.global.gossipEncryption.secretKey)) }} + {{- if not .Values.global.secretsBackend.vault.enabled }} + - name: GOSSIP_KEY + valueFrom: + secretKeyRef: + {{- if .Values.global.gossipEncryption.autoGenerate }} + name: {{ template "consul.fullname" . }}-gossip-encryption-key + key: key + {{- else if (and .Values.global.gossipEncryption.secretName .Values.global.gossipEncryption.secretKey) }} + name: {{ .Values.global.gossipEncryption.secretName }} + key: {{ .Values.global.gossipEncryption.secretKey }} + {{- end }} + {{- end }} + {{- end }} + {{- if (and .Values.global.enterpriseLicense.secretName .Values.global.enterpriseLicense.secretKey .Values.global.enterpriseLicense.enableLicenseAutoload (not .Values.global.acls.manageSystemACLs)) }} + - name: CONSUL_LICENSE_PATH + {{- if .Values.global.secretsBackend.vault.enabled }} + value: /vault/secrets/enterpriselicense.txt + {{- else }} + value: /consul/license/{{ .Values.global.enterpriseLicense.secretKey }} + {{- end }} + {{- end }} + {{- if .Values.global.tls.enabled }} + - name: CONSUL_HTTP_ADDR + value: https://localhost:8501 + {{- if .Values.global.tls.enableAutoEncrypt }} + - name: CONSUL_HTTP_SSL_VERIFY + value: "false" + {{- else }} + - name: CONSUL_CACERT + value: /consul/tls/ca/tls.crt + {{- end }} + {{- end }} + {{- include "consul.extraEnvironmentVars" .Values.client | nindent 12 }} + command: + - "/bin/sh" + - "-ec" + - | + CONSUL_FULLNAME="{{template "consul.fullname" . }}" + + {{- if and .Values.global.secretsBackend.vault.enabled .Values.global.gossipEncryption.secretName }} + GOSSIP_KEY=`cat /vault/secrets/gossip.txt` + {{- end }} + + {{ template "consul.extraconfig" }} + + exec /usr/local/bin/docker-entrypoint.sh consul agent \ + -node="${NODE}" \ + -advertise="${ADVERTISE_IP}" \ + -bind=0.0.0.0 \ + -client=0.0.0.0 \ + {{- range $k, $v := .Values.client.nodeMeta }} + -node-meta={{ $k }}:{{ $v }} \ + {{- end }} + -hcl='leave_on_terminate = true' \ + {{- if .Values.global.tls.enabled }} + {{- if .Values.global.peering.enabled }} + {{- if .Values.global.secretsBackend.vault.enabled }} + -hcl='tls { defaults { ca_file = "/vault/secrets/serverca.crt" }}' \ + {{- else }} + -hcl='tls { defaults { ca_file = "/consul/tls/ca/tls.crt" }}' \ + {{- end }} + {{- if .Values.global.tls.enableAutoEncrypt }} + -hcl='auto_encrypt = {tls = true}' \ + -hcl="auto_encrypt = {ip_san = [\"$HOST_IP\",\"$POD_IP\"]}" \ + -hcl='tls { grpc { use_auto_cert = true } }' \ + {{- else }} + -hcl='tls { defaults { cert_file = "/consul/tls/client/tls.crt" }}' \ + -hcl='tls { defaults { key_file = "/consul/tls/client/tls.key" }}' \ + {{- end }} + {{- if .Values.global.tls.verify }} + -hcl='tls { defaults { verify_outgoing = true }}' \ + {{- if not .Values.global.tls.enableAutoEncrypt }} + -hcl='tls { internal_rpc { verify_incoming = true }}' \ + -hcl='tls { internal_rpc { verify_server_hostname = true }}' \ + {{- end }} + {{- end }} + -hcl='ports { https = 8501 }' \ + {{- if .Values.global.tls.httpsOnly }} + -hcl='ports { http = -1 }' \ + {{- end }} + {{- else}} + {{- if .Values.global.secretsBackend.vault.enabled }} + -hcl='ca_file = "/vault/secrets/serverca.crt"' \ + {{- else }} + -hcl='ca_file = "/consul/tls/ca/tls.crt"' \ + {{- end }} + {{- if .Values.global.tls.enableAutoEncrypt }} + -hcl='auto_encrypt = {tls = true}' \ + -hcl="auto_encrypt = {ip_san = [\"$HOST_IP\",\"$POD_IP\"]}" \ + {{- else }} + -hcl='cert_file = "/consul/tls/client/tls.crt"' \ + -hcl='key_file = "/consul/tls/client/tls.key"' \ + {{- end }} + {{- if .Values.global.tls.verify }} + -hcl='verify_outgoing = true' \ + {{- if not .Values.global.tls.enableAutoEncrypt }} + -hcl='verify_incoming_rpc = true' \ + -hcl='verify_server_hostname = true' \ + {{- end }} + {{- end }} + -hcl='ports { https = 8501 }' \ + {{- if .Values.global.tls.httpsOnly }} + -hcl='ports { http = -1 }' \ + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.client.grpc }} + {{- if .Values.global.tls.enabled }} + -hcl='ports { grpc = -1, grpc_tls = 8502 }' \ + {{- else }} + -hcl='ports { grpc = 8502, grpc_tls = -1 }' \ + {{- end }} + {{- end }} + {{- if (and .Values.global.metrics.enabled .Values.global.metrics.enableAgentMetrics) }} + -hcl='telemetry { prometheus_retention_time = "{{ .Values.global.metrics.agentMetricsRetentionTime }}" }' \ + {{- end }} + {{- if .Values.global.adminPartitions.enabled }} + -hcl='partition = "{{ .Values.global.adminPartitions.name }}"' \ + {{- end }} + -config-dir=/consul/config \ + {{- if .Values.global.acls.manageSystemACLs }} + -config-dir=/consul/aclconfig \ + {{- end }} + {{- /* Always include the extraVolumes at the end so that users can + override other Consul settings. The last -config-dir takes + precedence. */}} + {{- range .Values.client.extraVolumes }} + {{- if .load }} + -config-dir=/consul/userconfig/{{ .name }} \ + {{- end }} + {{- end }} + -datacenter={{ .Values.global.datacenter }} \ + -data-dir=/consul/data \ + {{- if (or .Values.global.gossipEncryption.autoGenerate (and .Values.global.gossipEncryption.secretName .Values.global.gossipEncryption.secretKey)) }} + -encrypt="${GOSSIP_KEY}" \ + {{- end }} + {{- if .Values.client.join }} + {{- range $value := .Values.client.join }} + -retry-join={{ quote $value }} \ + {{- end }} + {{- else }} + {{- if .Values.server.enabled }} + {{- $serverSerfLANPort := .Values.server.ports.serflan.port -}} + {{- range $index := until (.Values.server.replicas | int) }} + -retry-join="${CONSUL_FULLNAME}-server-{{ $index }}.${CONSUL_FULLNAME}-server.${NAMESPACE}.svc:{{ $serverSerfLANPort }}" \ + {{- end }} + {{- end }} + {{- end }} + {{- range $value := .Values.global.recursors }} + -recursor={{ quote $value }} \ + {{- end }} + -config-dir=/consul/extra-config \ + -domain={{ .Values.global.domain }} + volumeMounts: + - name: data + mountPath: /consul/data + - name: config + mountPath: /consul/config + - name: extra-config + mountPath: /consul/extra-config + - name: tmp-extra-config + mountPath: /consul/tmp/extra-config + - mountPath: /consul/login + name: consul-data + readOnly: true + {{- if .Values.global.tls.enabled }} + {{- if not .Values.global.secretsBackend.vault.enabled }} + - name: consul-ca-cert + mountPath: /consul/tls/ca + readOnly: true + {{- if not .Values.global.tls.enableAutoEncrypt }} + - name: consul-client-cert + mountPath: /consul/tls/client + readOnly: true + {{- end }} + {{- end }} + {{- end }} + {{- range .Values.client.extraVolumes }} + - name: userconfig-{{ .name }} + readOnly: true + mountPath: /consul/userconfig/{{ .name }} + {{- end }} + {{- if .Values.global.acls.manageSystemACLs }} + - name: aclconfig + mountPath: /consul/aclconfig + {{- else }} + {{- if (and .Values.global.enterpriseLicense.secretName .Values.global.enterpriseLicense.secretKey .Values.global.enterpriseLicense.enableLicenseAutoload (not .Values.global.secretsBackend.vault.enabled)) }} + - name: consul-license + mountPath: /consul/license + readOnly: true + {{- end }} + {{- end }} + ports: + {{- if (or (not .Values.global.tls.enabled) (not .Values.global.tls.httpsOnly)) }} + - containerPort: 8500 + hostPort: 8500 + name: http + {{- end }} + {{- if .Values.global.tls.enabled }} + - containerPort: 8501 + hostPort: 8501 + name: https + {{- end }} + - containerPort: 8502 + hostPort: 8502 + name: grpc + - containerPort: 8301 + {{- if .Values.client.exposeGossipPorts }} + hostPort: 8301 + {{- end }} + protocol: "TCP" + name: serflan-tcp + - containerPort: 8301 + {{- if .Values.client.exposeGossipPorts }} + hostPort: 8301 + {{- end }} + protocol: "UDP" + name: serflan-udp + - containerPort: 8600 + name: dns-tcp + protocol: "TCP" + - containerPort: 8600 + name: dns-udp + protocol: "UDP" + readinessProbe: + # NOTE(mitchellh): when our HTTP status endpoints support the + # proper status codes, we should switch to that. This is temporary. + exec: + command: + - "/bin/sh" + - "-ec" + - | + {{- if .Values.global.tls.enabled }} + curl \ + -k \ + https://127.0.0.1:8501/v1/status/leader \ + {{- else }} + curl http://127.0.0.1:8500/v1/status/leader \ + {{- end }} + 2>/dev/null | grep -E '".+"' + {{- if .Values.client.resources }} + resources: + {{- if eq (typeOf .Values.client.resources) "string" }} + {{ tpl .Values.client.resources . | nindent 12 | trim }} + {{- else }} + {{- toYaml .Values.client.resources | nindent 12 }} + {{- end }} + {{- end }} + {{- if not .Values.global.openshift.enabled }} + securityContext: + {{- toYaml .Values.client.containerSecurityContext.client | nindent 12 }} + {{- end }} + {{- if .Values.client.extraContainers }} + {{ toYaml .Values.client.extraContainers | nindent 8 }} + {{- end }} + {{- if (or .Values.global.acls.manageSystemACLs (and .Values.global.tls.enabled (not .Values.global.tls.enableAutoEncrypt))) }} + initContainers: + {{- if .Values.global.acls.manageSystemACLs }} + - name: client-acl-init + image: {{ .Values.global.imageK8S }} + {{ template "consul.imagePullPolicy" . }} + env: + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + {{- include "consul.consulK8sConsulServerEnvVars" . | nindent 8 }} + {{- if .Values.global.acls.manageSystemACLs }} + - name: CONSUL_LOGIN_AUTH_METHOD + value: {{ template "consul.fullname" . }}-k8s-component-auth-method + - name: CONSUL_LOGIN_META + value: "component=client,pod=$(NAMESPACE)/$(POD_NAME)" + {{- end }} + - name: CONSUL_LOGIN_DATACENTER + value: {{ .Values.global.datacenter }} + command: + - "/bin/sh" + - "-ec" + - | + exec consul-k8s-control-plane acl-init \ + -log-level={{ default .Values.global.logLevel .Values.client.logLevel }} \ + -log-json={{ .Values.global.logJSON }} \ + -init-type="client" + volumeMounts: + - name: aclconfig + mountPath: /consul/aclconfig + - mountPath: /consul/login + name: consul-data + readOnly: false + {{- if (and .Values.global.tls.enabled (not .Values.global.secretsBackend.vault.enabled) (not .Values.externalServers.useSystemRoots)) }} + - name: consul-ca-cert + mountPath: /consul/tls/ca + readOnly: false + {{- end }} + resources: + requests: + memory: "25Mi" + cpu: "50m" + limits: + memory: "25Mi" + cpu: "50m" + {{- if not .Values.global.openshift.enabled }} + securityContext: + {{- toYaml .Values.client.containerSecurityContext.aclInit | nindent 10 }} + {{- end }} + {{- end }} + {{- if and .Values.global.tls.enabled (not .Values.global.tls.enableAutoEncrypt) }} + - name: client-tls-init + image: "{{ default .Values.global.image .Values.client.image }}" + {{ template "consul.imagePullPolicy" . }} + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + command: + - "/bin/sh" + - "-ec" + - | + cd /consul/tls/client + consul tls cert create -client \ + -additional-ipaddress=${HOST_IP} \ + -additional-ipaddress=${POD_IP} \ + -dc={{ .Values.global.datacenter }} \ + -domain={{ .Values.global.domain }} \ + -ca=/consul/tls/ca/cert/tls.crt \ + -key=/consul/tls/ca/key/tls.key + mv {{ .Values.global.datacenter }}-client-{{ .Values.global.domain }}-0.pem tls.crt + mv {{ .Values.global.datacenter }}-client-{{ .Values.global.domain }}-0-key.pem tls.key + volumeMounts: + {{- if not .Values.global.secretsBackend.vault.enabled }} + - name: consul-client-cert + mountPath: /consul/tls/client + - name: consul-ca-cert + mountPath: /consul/tls/ca/cert + readOnly: true + - name: consul-ca-key + mountPath: /consul/tls/ca/key + readOnly: true + {{- end }} + resources: + requests: + memory: "50Mi" + cpu: "50m" + limits: + memory: "50Mi" + cpu: "50m" + {{- if not .Values.global.openshift.enabled }} + securityContext: + {{- toYaml .Values.client.containerSecurityContext.tlsInit | nindent 10 }} + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.client.nodeSelector }} + nodeSelector: + {{ tpl .Values.client.nodeSelector . | indent 8 | trim }} + {{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/client-podsecuritypolicy.yaml b/kubernetes-vault/consul/templates/client-podsecuritypolicy.yaml new file mode 100644 index 0000000..0121bdf --- /dev/null +++ b/kubernetes-vault/consul/templates/client-podsecuritypolicy.yaml @@ -0,0 +1,76 @@ +{{- if (and .Values.global.enablePodSecurityPolicies (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled))) }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "consul.fullname" . }}-client + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: client +spec: + privileged: false + # Required to prevent escalations to root. + allowPrivilegeEscalation: false + # This is redundant with non-root + disallow privilege escalation, + # but we can provide it for defense in depth. + requiredDropCapabilities: + - ALL + # Allow core volume types. + volumes: + - 'configMap' + - 'emptyDir' + - 'projected' + - 'secret' + - 'downwardAPI' + {{- if .Values.client.dataDirectoryHostPath }} + - 'hostPath' + {{- end }} + {{- if .Values.client.hostNetwork }} + hostNetwork: {{ .Values.client.hostNetwork }} + {{- else }} + hostNetwork: false + {{- end }} + hostPorts: + {{- if (not (and .Values.global.tls.enabled .Values.global.tls.httpsOnly)) }} + # HTTP Port + - min: 8500 + max: 8500 + {{- end }} + {{- if .Values.global.tls.enabled }} + # HTTPS port + - min: 8501 + max: 8501 + {{- end }} + {{- if .Values.client.grpc }} + # gRPC Port + - min: 8502 + max: 8502 + {{- end }} + {{- if (or .Values.client.exposeGossipPorts .Values.client.hostNetwork) }} + - min: 8301 + max: 8301 + {{- end }} + {{- if .Values.client.hostNetwork }} + - min: 8600 + max: 8600 + {{- end }} + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' + readOnlyRootFilesystem: false + {{- if .Values.client.dataDirectoryHostPath }} + allowedHostPaths: + - pathPrefix: {{ .Values.client.dataDirectoryHostPath | quote }} + readOnly: false + {{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/client-role.yaml b/kubernetes-vault/consul/templates/client-role.yaml new file mode 100644 index 0000000..7f05b82 --- /dev/null +++ b/kubernetes-vault/consul/templates/client-role.yaml @@ -0,0 +1,43 @@ +{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "consul.fullname" . }}-client + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: client +{{- if (or .Values.global.acls.manageSystemACLs .Values.global.enablePodSecurityPolicies .Values.global.openshift.enabled) }} +rules: +{{- if .Values.global.enablePodSecurityPolicies }} + - apiGroups: ["policy"] + resources: ["podsecuritypolicies"] + resourceNames: + - {{ template "consul.fullname" . }}-client + verbs: + - use +{{- end }} +{{- if .Values.global.acls.manageSystemACLs }} + - apiGroups: [""] + resources: + - secrets + resourceNames: + - {{ template "consul.fullname" . }}-client-acl-token + verbs: + - get +{{- end }} +{{- if .Values.global.openshift.enabled}} + - apiGroups: ["security.openshift.io"] + resources: ["securitycontextconstraints"] + resourceNames: + - {{ template "consul.fullname" . }}-client + verbs: + - use +{{- end}} +{{- else}} +rules: [] +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/client-rolebinding.yaml b/kubernetes-vault/consul/templates/client-rolebinding.yaml new file mode 100644 index 0000000..b034c70 --- /dev/null +++ b/kubernetes-vault/consul/templates/client-rolebinding.yaml @@ -0,0 +1,20 @@ +{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "consul.fullname" . }}-client + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: client +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "consul.fullname" . }}-client +subjects: + - kind: ServiceAccount + name: {{ template "consul.fullname" . }}-client +{{- end }} diff --git a/kubernetes-vault/consul/templates/client-securitycontextconstraints.yaml b/kubernetes-vault/consul/templates/client-securitycontextconstraints.yaml new file mode 100644 index 0000000..c14dd1c --- /dev/null +++ b/kubernetes-vault/consul/templates/client-securitycontextconstraints.yaml @@ -0,0 +1,61 @@ +{{- if (and .Values.global.openshift.enabled (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled))) }} +apiVersion: security.openshift.io/v1 +kind: SecurityContextConstraints +metadata: + name: {{ template "consul.fullname" . }}-client + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: client + annotations: + kubernetes.io/description: {{ template "consul.fullname" . }}-client are the security context constraints required + to run the consul client. +# Iff. allowHostDirVolumePlugin is true, hostPath must be included in volumes (see below). +{{- if .Values.client.dataDirectoryHostPath }} +allowHostDirVolumePlugin: true +{{- else }} +allowHostDirVolumePlugin: false +{{- end}} +allowHostIPC: false +allowHostNetwork: {{ .Values.client.hostNetwork }} +allowHostPID: false +allowHostPorts: true +allowPrivilegeEscalation: true +allowPrivilegedContainer: false +allowedCapabilities: null +defaultAddCapabilities: null +fsGroup: + type: MustRunAs +groups: [] +priority: null +readOnlyRootFilesystem: false +requiredDropCapabilities: +- KILL +- MKNOD +- SETUID +- SETGID +runAsUser: + type: MustRunAsRange +seLinuxContext: + type: MustRunAs +supplementalGroups: + type: MustRunAs +users: [] +volumes: +# This list must be in alphabetical order to match the post-reconcile order enforced by OpenShift admission hooks. +# Furthermore, hostPath must be included explicitly if allowHostDirVolumePlugin is true, as it will otherwise be +# added by OpenShift. It must be excluded if allowHostDirVolumePlugin is false per OpenShift requirements. +# This avoids false positives in change detection by third-party diff tools (e.g. ArgoCD) that respect list order. +- configMap +- downwardAPI +- emptyDir +{{- if .Values.client.dataDirectoryHostPath }} +- hostPath +{{- end }} +- persistentVolumeClaim +- projected +- secret +{{- end}} diff --git a/kubernetes-vault/consul/templates/client-serviceaccount.yaml b/kubernetes-vault/consul/templates/client-serviceaccount.yaml new file mode 100644 index 0000000..addd757 --- /dev/null +++ b/kubernetes-vault/consul/templates/client-serviceaccount.yaml @@ -0,0 +1,23 @@ +{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "consul.fullname" . }}-client + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: client + {{- if .Values.client.serviceAccount.annotations }} + annotations: + {{ tpl .Values.client.serviceAccount.annotations . | nindent 4 | trim }} + {{- end }} +{{- with .Values.global.imagePullSecrets }} +imagePullSecrets: +{{- range . }} + - name: {{ .name }} +{{- end }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/client-tmp-extra-config-configmap.yaml b/kubernetes-vault/consul/templates/client-tmp-extra-config-configmap.yaml new file mode 100644 index 0000000..a379157 --- /dev/null +++ b/kubernetes-vault/consul/templates/client-tmp-extra-config-configmap.yaml @@ -0,0 +1,21 @@ +{{- if (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} +# ConfigMap that is used as a temporary landing spot so that the container command +# in the client-daemonset where it needs to be transformed. ConfigMaps create +# read only volumes so it needs to be copied and transformed to the extra-config +# emptyDir volume where all final extra cofngi lives for use in consul. (locality-init +# also writes to extra-config volume.) +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "consul.fullname" . }}-client-tmp-extra-config + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: client +data: + extra-from-values.json: |- +{{ tpl .Values.client.extraConfig . | trimAll "\"" | indent 4 }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/cni-clusterrole.yaml b/kubernetes-vault/consul/templates/cni-clusterrole.yaml new file mode 100644 index 0000000..773942c --- /dev/null +++ b/kubernetes-vault/consul/templates/cni-clusterrole.yaml @@ -0,0 +1,38 @@ +{{- if .Values.connectInject.cni.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "consul.fullname" . }}-cni + namespace: {{ default .Release.Namespace .Values.connectInject.cni.namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: cni +rules: +- apiGroups: [""] + resources: + - pods + verbs: + - get + - list + - watch + - patch + - update +- apiGroups: ["policy"] + resources: + - podsecuritypolicies + resourceNames: + - {{ template "consul.fullname" . }}-cni + verbs: + - use +{{- if .Values.global.openshift.enabled}} +- apiGroups: ["security.openshift.io"] + resources: ["securitycontextconstraints"] + resourceNames: + - {{ template "consul.fullname" . }}-cni + verbs: + - use +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/cni-clusterrolebinding.yaml b/kubernetes-vault/consul/templates/cni-clusterrolebinding.yaml new file mode 100644 index 0000000..4b86038 --- /dev/null +++ b/kubernetes-vault/consul/templates/cni-clusterrolebinding.yaml @@ -0,0 +1,20 @@ +{{- if .Values.connectInject.cni.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "consul.fullname" . }}-cni + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: cni +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "consul.fullname" . }}-cni +subjects: +- kind: ServiceAccount + name: {{ template "consul.fullname" . }}-cni + namespace: {{ default .Release.Namespace .Values.connectInject.cni.namespace }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/cni-daemonset.yaml b/kubernetes-vault/consul/templates/cni-daemonset.yaml new file mode 100644 index 0000000..a93e3ae --- /dev/null +++ b/kubernetes-vault/consul/templates/cni-daemonset.yaml @@ -0,0 +1,92 @@ +{{- if (and (.Values.connectInject.cni.enabled) (not .Values.connectInject.enabled)) }}{{ fail "connectInject.enabled must be true if connectInject.cni.enabled is true" }}{{ end -}} +{{- if .Values.connectInject.cni.enabled }} +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ template "consul.fullname" . }}-cni + namespace: {{ default .Release.Namespace .Values.connectInject.cni.namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: cni + {{- if .Values.global.extraLabels }} + {{- toYaml .Values.global.extraLabels | nindent 4 }} + {{- end }} +spec: + {{- if .Values.connectInject.cni.updateStrategy }} + updateStrategy: + {{ tpl .Values.connectInject.cni.updateStrategy . | nindent 4 | trim }} + {{- end }} + selector: + matchLabels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: cni + template: + metadata: + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: cni + {{- if .Values.global.extraLabels }} + {{- toYaml .Values.global.extraLabels | nindent 8 }} + {{- end }} + annotations: + consul.hashicorp.com/connect-inject: "false" + consul.hashicorp.com/mesh-inject: "false" + spec: + # consul-cni only runs on linux operating systems + nodeSelector: + kubernetes.io/os: linux + tolerations: + # Mark the pod as a critical add-on for rescheduling. + - key: CriticalAddonsOnly + operator: Exists + - effect: NoExecute + operator: Exists + # Tell kubernetes that this daemonset is critical so that it will be scheduled on a new node before other pods + priorityClassName: system-node-critical + serviceAccountName: {{ template "consul.fullname" . }}-cni + {{- if not .Values.global.openshift.enabled }} + securityContext: + {{- toYaml .Values.connectInject.cni.securityContext | nindent 8 -}} + {{- end }} + # Minimize downtime during a rolling upgrade or deletion; tell Kubernetes to do a "force + # deletion": https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods. + terminationGracePeriodSeconds: 10 + containers: + # This container installs the consul CNI binaries and CNI network config file on each node + - name: install-cni + image: {{ .Values.global.imageK8S }} + {{ template "consul.imagePullPolicy" . }} + securityContext: + privileged: true + command: + - consul-k8s-control-plane + - install-cni + - -log-level={{ default .Values.global.logLevel .Values.connectInject.cni.logLevel }} + - -cni-bin-dir={{ .Values.connectInject.cni.cniBinDir }} + - -cni-net-dir={{ .Values.connectInject.cni.cniNetDir }} + - -multus={{ .Values.connectInject.cni.multus }} + {{- with .Values.connectInject.cni.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + - mountPath: {{ .Values.connectInject.cni.cniBinDir }} + name: cni-bin-dir + - mountPath: {{ .Values.connectInject.cni.cniNetDir }} + name: cni-net-dir + volumes: + # Used to install CNI. + - name: cni-bin-dir + hostPath: + path: {{ .Values.connectInject.cni.cniBinDir }} + - name: cni-net-dir + hostPath: + path: {{ .Values.connectInject.cni.cniNetDir }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/cni-networkattachmentdefinition.yaml b/kubernetes-vault/consul/templates/cni-networkattachmentdefinition.yaml new file mode 100644 index 0000000..80ef50b --- /dev/null +++ b/kubernetes-vault/consul/templates/cni-networkattachmentdefinition.yaml @@ -0,0 +1,25 @@ +{{- if (and (.Values.connectInject.cni.enabled) (.Values.connectInject.cni.multus)) }} +apiVersion: "k8s.cni.cncf.io/v1" +kind: NetworkAttachmentDefinition +metadata: + name: {{ template "consul.fullname" . }}-cni + namespace: {{ default .Release.Namespace .Values.connectInject.cni.namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: cni +spec: + config: '{ + "cniVersion": "0.3.1", + "type": "consul-cni", + "cni_bin_dir": "{{ .Values.connectInject.cni.cniBinDir }}", + "cni_net_dir": "{{ .Values.connectInject.cni.cniNetDir }}", + "kubeconfig": "ZZZ-consul-cni-kubeconfig", + "log_level": "{{ default .Values.global.logLevel .Values.connectInject.cni.logLevel }}", + "multus": true, + "name": "consul-cni", + "type": "consul-cni" + }' +{{- end }} diff --git a/kubernetes-vault/consul/templates/cni-podsecuritypolicy.yaml b/kubernetes-vault/consul/templates/cni-podsecuritypolicy.yaml new file mode 100644 index 0000000..b600ed1 --- /dev/null +++ b/kubernetes-vault/consul/templates/cni-podsecuritypolicy.yaml @@ -0,0 +1,31 @@ +{{- if (and .Values.connectInject.cni.enabled .Values.global.enablePodSecurityPolicies) }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "consul.fullname" . }}-cni + namespace: {{ default .Release.Namespace .Values.connectInject.cni.namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: cni +spec: + privileged: true + # GKE requires that allowPrivilegeEscalation:true if privileged: true. + allowPrivilegeEscalation: true + volumes: + - hostPath + - secret + - emptyDir + hostNetwork: false + readOnlyRootFilesystem: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' +{{- end }} diff --git a/kubernetes-vault/consul/templates/cni-resourcequota.yaml b/kubernetes-vault/consul/templates/cni-resourcequota.yaml new file mode 100644 index 0000000..054c306 --- /dev/null +++ b/kubernetes-vault/consul/templates/cni-resourcequota.yaml @@ -0,0 +1,22 @@ +{{- if .Values.connectInject.cni.enabled }} +apiVersion: v1 +kind: ResourceQuota +metadata: + name: {{ template "consul.fullname" . }}-cni + namespace: {{ default .Release.Namespace .Values.connectInject.cni.namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: cni +spec: + hard: + pods: {{ .Values.connectInject.cni.resourceQuota.pods | quote }} + scopeSelector: + matchExpressions: + - operator: In + scopeName: PriorityClass + values: + - system-node-critical +{{- end }} diff --git a/kubernetes-vault/consul/templates/cni-securitycontextconstraints.yaml b/kubernetes-vault/consul/templates/cni-securitycontextconstraints.yaml new file mode 100644 index 0000000..cb60104 --- /dev/null +++ b/kubernetes-vault/consul/templates/cni-securitycontextconstraints.yaml @@ -0,0 +1,55 @@ +{{- if (and (.Values.connectInject.cni.enabled) (.Values.global.openshift.enabled)) }} +apiVersion: security.openshift.io/v1 +kind: SecurityContextConstraints +metadata: + name: {{ template "consul.fullname" . }}-cni + namespace: {{ default .Release.Namespace .Values.connectInject.cni.namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: cni + annotations: + kubernetes.io/description: {{ template "consul.fullname" . }}-cni are the security context constraints required + to run consul-cni. +# Iff. allowHostDirVolumePlugin is true, hostPath must be included in volumes (see below). +allowHostDirVolumePlugin: true +allowHostIPC: false +allowHostNetwork: false +allowHostPID: false +allowHostPorts: false +allowPrivilegeEscalation: true +allowPrivilegedContainer: true +allowedCapabilities: null +defaultAddCapabilities: null +fsGroup: + type: MustRunAs +groups: [] +priority: null +readOnlyRootFilesystem: false +requiredDropCapabilities: +- KILL +- MKNOD +- SETUID +- SETGID +runAsUser: + type: MustRunAsRange +seLinuxContext: + type: MustRunAs +supplementalGroups: + type: MustRunAs +users: [] +volumes: +# This list must be in alphabetical order to match the post-reconcile order enforced by OpenShift admission hooks. +# Furthermore, hostPath must be included explicitly if allowHostDirVolumePlugin is true, as it will otherwise be +# added by OpenShift. It must be excluded if allowHostDirVolumePlugin is false per OpenShift requirements. +# This avoids false positives in change detection by third-party diff tools (e.g. ArgoCD) that respect list order. +- configMap +- downwardAPI +- emptyDir +- hostPath +- persistentVolumeClaim +- projected +- secret +{{- end }} diff --git a/kubernetes-vault/consul/templates/cni-serviceaccount.yaml b/kubernetes-vault/consul/templates/cni-serviceaccount.yaml new file mode 100644 index 0000000..cf4250b --- /dev/null +++ b/kubernetes-vault/consul/templates/cni-serviceaccount.yaml @@ -0,0 +1,19 @@ +{{- if .Values.connectInject.cni.enabled }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "consul.fullname" . }}-cni + namespace: {{ default .Release.Namespace .Values.connectInject.cni.namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: cni +{{- with .Values.global.imagePullSecrets }} +imagePullSecrets: +{{- range . }} +- name: {{ .name }} +{{- end }} +{{- end }} +{{- end}} diff --git a/kubernetes-vault/consul/templates/connect-inject-clusterrole.yaml b/kubernetes-vault/consul/templates/connect-inject-clusterrole.yaml new file mode 100644 index 0000000..9c8596b --- /dev/null +++ b/kubernetes-vault/consul/templates/connect-inject-clusterrole.yaml @@ -0,0 +1,291 @@ +{{- if or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled) }} +# The ClusterRole to enable the Connect injector to get, list, watch and patch MutatingWebhookConfiguration. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "consul.fullname" . }}-connect-injector + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: connect-injector +rules: +- apiGroups: + - consul.hashicorp.com + resources: + - servicedefaults + - serviceresolvers + - proxydefaults + - meshes + - exportedservices + - servicerouters + - servicesplitters + - serviceintentions + - ingressgateways + - terminatinggateways + - gatewayclassconfigs + - meshservices + - samenessgroups + - controlplanerequestlimits + - routeretryfilters + - routetimeoutfilters + - routeauthfilters + - gatewaypolicies + - registrations + {{- if .Values.global.peering.enabled }} + - peeringacceptors + - peeringdialers + {{- end }} + - jwtproviders + - routeauthfilters + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - consul.hashicorp.com + resources: + - servicedefaults/status + - serviceresolvers/status + - proxydefaults/status + - meshes/status + - exportedservices/status + - servicerouters/status + - servicesplitters/status + - serviceintentions/status + - ingressgateways/status + - terminatinggateways/status + - samenessgroups/status + - controlplanerequestlimits/status + - registrations/status + {{- if .Values.global.peering.enabled }} + - peeringacceptors/status + - peeringdialers/status + {{- end }} + - jwtproviders/status + - routeauthfilters/status + - gatewaypolicies/status + verbs: + - get + - patch + - update +{{- if (mustHas "resource-apis" .Values.global.experiments) }} +- apiGroups: + - auth.consul.hashicorp.com + resources: + - trafficpermissions + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - auth.consul.hashicorp.com + resources: + - trafficpermissions/status + verbs: + - get + - patch + - update +- apiGroups: + - mesh.consul.hashicorp.com + resources: + - gatewayclassconfigs + - gatewayclasses + - meshconfigurations + - grpcroutes + - httproutes + - meshgateways + - apigateways + - tcproutes + - proxyconfigurations + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - mesh.consul.hashicorp.com + resources: + - gatewayclassconfigs/status + - gatewayclasses/status + - meshconfigurations/status + - grpcroutes/status + - httproutes/status + - meshgateways/status + - apigateways/status + - tcproutes/status + - proxyconfigurations/status + verbs: + - get + - patch + - update +- apiGroups: + - multicluster.consul.hashicorp.com + resources: + - exportedservices + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - multicluster.consul.hashicorp.com + resources: + - exportedservices/status + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +{{- end }} +- apiGroups: [ "" ] + resources: [ "secrets", "serviceaccounts", "endpoints", "services", "namespaces", "nodes" ] + verbs: + - create + - get + - list + - watch + - delete + - update +- apiGroups: [ "rbac.authorization.k8s.io" ] + resources: [ "roles", "rolebindings" ] + verbs: + - get + - list + - watch + - delete + - create + - update +- apiGroups: [ "" ] + resources: + - pods + verbs: + - "get" + - "list" + - "watch" + - "update" +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - create + - get + - list + - update +{{- if (and .Values.global.secretsBackend.vault.enabled .Values.global.secretsBackend.vault.connectInjectRole .Values.global.secretsBackend.vault.connectInject.tlsCert.secretName .Values.global.secretsBackend.vault.connectInject.caCert.secretName)}} +- apiGroups: + - admissionregistration.k8s.io + resources: + - mutatingwebhookconfigurations + - validatingwebhookconfigurations + verbs: + - get + - list + - watch + - patch +{{- end }} +{{- if .Values.global.peering.enabled }} +- apiGroups: [ "" ] + resources: [ "secrets" ] + verbs: + - "get" + - "list" + - "watch" + - "create" + - "update" + - "delete" +{{- end }} +- apiGroups: [ "policy" ] + resources: [ "podsecuritypolicies" ] + verbs: + - use +- apiGroups: + - gateway.networking.k8s.io + resources: + - gatewayclasses + - gateways + - httproutes + - tcproutes + - referencegrants + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - gateway.networking.k8s.io + resources: + - gatewayclasses/finalizers + - gateways/finalizers + - httproutes/finalizers + - tcproutes/finalizers + verbs: + - update +- apiGroups: + - gateway.networking.k8s.io + resources: + - gatewayclasses/status + - gateways/status + - httproutes/status + - tcproutes/status + verbs: + - get + - patch + - update +- apiGroups: + - apps + resources: + - deployments + verbs: + - create + - get + - list + - update + - watch + - delete +- apiGroups: + - core + resources: + - services + verbs: + - watch + - list +- apiGroups: [ "" ] + resources: [ "secrets" ] + verbs: + - "get" + - "list" + - "watch" +{{- if .Values.global.openshift.enabled }} +- apiGroups: + - security.openshift.io + resources: + - securitycontextconstraints + resourceNames: + - {{ .Values.connectInject.apiGateway.managedGatewayClass.openshiftSCCName }} + verbs: + - use + {{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/connect-inject-clusterrolebinding.yaml b/kubernetes-vault/consul/templates/connect-inject-clusterrolebinding.yaml new file mode 100644 index 0000000..c380adb --- /dev/null +++ b/kubernetes-vault/consul/templates/connect-inject-clusterrolebinding.yaml @@ -0,0 +1,20 @@ +{{- if or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled) }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "consul.fullname" . }}-connect-injector + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: connect-injector +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "consul.fullname" . }}-connect-injector +subjects: +- kind: ServiceAccount + name: {{ template "consul.fullname" . }}-connect-injector + namespace: {{ .Release.Namespace }} +{{- end }} \ No newline at end of file diff --git a/kubernetes-vault/consul/templates/connect-inject-deployment.yaml b/kubernetes-vault/consul/templates/connect-inject-deployment.yaml new file mode 100644 index 0000000..5aaa50a --- /dev/null +++ b/kubernetes-vault/consul/templates/connect-inject-deployment.yaml @@ -0,0 +1,371 @@ +{{- if and .Values.global.peering.enabled (not .Values.connectInject.enabled) }}{{ fail "setting global.peering.enabled to true requires connectInject.enabled to be true" }}{{ end }} +{{- if and .Values.global.peering.enabled (not .Values.global.tls.enabled) }}{{ fail "setting global.peering.enabled to true requires global.tls.enabled to be true" }}{{ end }} +{{- if and .Values.global.peering.enabled (not .Values.meshGateway.enabled) }}{{ fail "setting global.peering.enabled to true requires meshGateway.enabled to be true" }}{{ end }} +{{- if (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled)) }} +{{- if and .Values.global.adminPartitions.enabled (not .Values.global.enableConsulNamespaces) }}{{ fail "global.enableConsulNamespaces must be true if global.adminPartitions.enabled=true" }}{{ end }} +{{ template "consul.validateVaultWebhookCertConfiguration" . }} +{{- template "consul.reservedNamesFailer" (list .Values.connectInject.consulNamespaces.consulDestinationNamespace "connectInject.consulNamespaces.consulDestinationNamespace") }} +{{- if and .Values.externalServers.enabled (not .Values.externalServers.hosts) }}{{ fail "externalServers.hosts must be set if externalServers.enabled is true" }}{{ end -}} +{{- if and .Values.externalServers.enabled .Values.global.cloud.enabled }} + {{- if and (gt (len .Values.externalServers.hosts) 0) (regexMatch ".+.hashicorp.cloud$" ( first .Values.externalServers.hosts )) }}{{fail "global.cloud.enabled cannot be used in combination with an HCP-managed cluster address in externalServers.hosts. global.cloud.enabled is for linked self-managed clusters."}}{{- end }} +{{- end }} +{{- if and .Values.externalServers.skipServerWatch (not .Values.externalServers.enabled) }}{{ fail "externalServers.enabled must be set if externalServers.skipServerWatch is true" }}{{ end -}} +{{- $dnsEnabled := (or (and (ne (.Values.dns.enabled | toString) "-") .Values.dns.enabled) (and (eq (.Values.dns.enabled | toString) "-") .Values.connectInject.transparentProxy.defaultEnabled)) -}} +{{- $dnsRedirectionEnabled := (or (and (ne (.Values.dns.enableRedirection | toString) "-") .Values.dns.enableRedirection) (and (eq (.Values.dns.enableRedirection | toString) "-") .Values.connectInject.transparentProxy.defaultEnabled)) -}} +{{ template "consul.validateRequiredCloudSecretsExist" . }} +{{ template "consul.validateCloudSecretKeys" . }} +{{ template "consul.validateResourceAPIs" . }} +# The deployment for running the Connect sidecar injector +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "consul.fullname" . }}-connect-injector + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: connect-injector + {{- if .Values.global.extraLabels }} + {{- toYaml .Values.global.extraLabels | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.connectInject.replicas }} + selector: + matchLabels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: connect-injector + template: + metadata: + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: connect-injector + {{- if .Values.connectInject.extraLabels }} + {{- toYaml .Values.connectInject.extraLabels | nindent 8 }} + {{- end }} + {{- if .Values.global.extraLabels }} + {{- toYaml .Values.global.extraLabels | nindent 8 }} + {{- end }} + annotations: + "consul.hashicorp.com/connect-inject": "false" + "consul.hashicorp.com/mesh-inject": "false" + {{- if .Values.connectInject.annotations }} + {{- tpl .Values.connectInject.annotations . | nindent 8 }} + {{- end }} + {{- if (and .Values.global.secretsBackend.vault.enabled .Values.global.tls.enabled) }} + "vault.hashicorp.com/agent-init-first": "true" + "vault.hashicorp.com/agent-inject": "true" + {{- if .Values.global.secretsBackend.vault.connectInjectRole }} + "vault.hashicorp.com/role": {{ .Values.global.secretsBackend.vault.connectInjectRole }} + {{ else }} + "vault.hashicorp.com/role": {{ .Values.global.secretsBackend.vault.consulCARole }} + {{ end }} + "vault.hashicorp.com/agent-inject-secret-serverca.crt": {{ .Values.global.tls.caCert.secretName }} + "vault.hashicorp.com/agent-inject-template-serverca.crt": {{ template "consul.serverTLSCATemplate" . }} + {{- if .Values.global.secretsBackend.vault.connectInject.caCert.secretName }} + {{- with .Values.global.secretsBackend.vault.connectInject.caCert }} + "vault.hashicorp.com/agent-inject-secret-ca.crt": {{ .secretName }} + "vault.hashicorp.com/agent-inject-template-ca.crt": {{ template "consul.vaultCATemplate" . }} + "vault.hashicorp.com/secret-volume-path-ca.crt": "/vault/secrets/connect-injector/certs" + {{- end }} + {{- end }} + {{- if .Values.global.secretsBackend.vault.connectInject.tlsCert.secretName }} + "vault.hashicorp.com/agent-inject-secret-tls.crt": {{ .Values.global.secretsBackend.vault.connectInject.tlsCert.secretName }} + "vault.hashicorp.com/agent-inject-template-tls.crt": {{ include "consul.connectInjectWebhookTLSCertTemplate" . }} + "vault.hashicorp.com/secret-volume-path-tls.crt": "/vault/secrets/connect-injector/certs" + "vault.hashicorp.com/agent-inject-secret-tls.key": {{ .Values.global.secretsBackend.vault.connectInject.tlsCert.secretName }} + "vault.hashicorp.com/agent-inject-template-tls.key": {{ include "consul.connectInjectWebhookTLSKeyTemplate" . }} + "vault.hashicorp.com/secret-volume-path-tls.key": "/vault/secrets/connect-injector/certs" + {{- end }} + {{- if and .Values.global.secretsBackend.vault.ca.secretName .Values.global.secretsBackend.vault.ca.secretKey }} + "vault.hashicorp.com/agent-extra-secret": "{{ .Values.global.secretsBackend.vault.ca.secretName }}" + "vault.hashicorp.com/ca-cert": "/vault/custom/{{ .Values.global.secretsBackend.vault.ca.secretKey }}" + {{- end }} + {{- if .Values.global.secretsBackend.vault.agentAnnotations }} + {{ tpl .Values.global.secretsBackend.vault.agentAnnotations . | nindent 8 | trim }} + {{- end }} + {{- if (and (.Values.global.secretsBackend.vault.vaultNamespace) (not (hasKey (default "" .Values.global.secretsBackend.vault.agentAnnotations | fromYaml) "vault.hashicorp.com/namespace")))}} + "vault.hashicorp.com/namespace": "{{ .Values.global.secretsBackend.vault.vaultNamespace }}" + {{- end }} + {{- end }} + spec: + serviceAccountName: {{ template "consul.fullname" . }}-connect-injector + containers: + - name: sidecar-injector + image: "{{ default .Values.global.imageK8S .Values.connectInject.image }}" + {{ template "consul.imagePullPolicy" . }} + ports: + - containerPort: 8080 + name: webhook-server + protocol: TCP + {{- include "consul.restrictedSecurityContext" . | nindent 10 }} + env: + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + {{- include "consul.consulK8sConsulServerEnvVars" . | nindent 12 }} + {{- if .Values.global.acls.manageSystemACLs }} + - name: CONSUL_LOGIN_AUTH_METHOD + {{- if and .Values.global.federation.enabled .Values.global.federation.primaryDatacenter }} + value: {{ template "consul.fullname" . }}-k8s-component-auth-method-{{ .Values.global.datacenter }} + {{- else }} + value: {{ template "consul.fullname" . }}-k8s-component-auth-method + {{- end }} + - name: CONSUL_LOGIN_DATACENTER + {{- if and .Values.global.federation.enabled .Values.global.federation.primaryDatacenter }} + value: {{ .Values.global.federation.primaryDatacenter }} + {{- else }} + value: {{ .Values.global.datacenter }} + {{- end }} + - name: CONSUL_LOGIN_META + value: "component=connect-injector,pod=$(NAMESPACE)/$(POD_NAME)" + {{- end }} + {{- if (and .Values.connectInject.aclInjectToken.secretName .Values.connectInject.aclInjectToken.secretKey) }} + - name: CONSUL_ACL_TOKEN + valueFrom: + secretKeyRef: + name: {{ .Values.connectInject.aclInjectToken.secretName }} + key: {{ .Values.connectInject.aclInjectToken.secretKey }} + {{- end }} + command: + - "/bin/sh" + - "-ec" + - | + exec consul-k8s-control-plane inject-connect \ + {{- if .Values.global.federation.enabled }} + -enable-federation \ + {{- end }} + -log-level={{ default .Values.global.logLevel .Values.connectInject.logLevel }} \ + -log-json={{ .Values.global.logJSON }} \ + -default-inject={{ .Values.connectInject.default }} \ + -consul-image="{{ default .Values.global.image .Values.connectInject.imageConsul }}" \ + -consul-dataplane-image="{{ .Values.global.imageConsulDataplane }}" \ + -consul-k8s-image="{{ default .Values.global.imageK8S .Values.connectInject.image }}" \ + -release-name="{{ .Release.Name }}" \ + -release-namespace="{{ .Release.Namespace }}" \ + -resource-prefix={{ template "consul.fullname" . }} \ + -listen=:8080 \ + {{- if (mustHas "resource-apis" .Values.global.experiments) }} + -enable-resource-apis=true \ + {{- end }} + {{- if (mustHas "v2tenancy" .Values.global.experiments) }} + -enable-v2tenancy=true \ + {{- end }} + {{- range $k, $v := .Values.connectInject.consulNode.meta }} + -node-meta={{ $k }}={{ $v }} \ + {{- end }} + {{- if .Values.connectInject.transparentProxy.defaultEnabled }} + -default-enable-transparent-proxy=true \ + {{- else }} + -default-enable-transparent-proxy=false \ + {{- end }} + -enable-cni={{ .Values.connectInject.cni.enabled }} \ + {{- if .Values.global.peering.enabled }} + -enable-peering=true \ + {{- end }} + {{- if .Values.global.openshift.enabled }} + -enable-openshift \ + {{- end }} + {{- if .Values.connectInject.transparentProxy.defaultOverwriteProbes }} + -transparent-proxy-default-overwrite-probes=true \ + {{- else }} + -transparent-proxy-default-overwrite-probes=false \ + {{- end }} + {{- if (and $dnsEnabled $dnsRedirectionEnabled) }} + -enable-consul-dns=true \ + {{- end }} + {{- if .Values.global.openshift.enabled }} + -enable-openshift \ + {{- end }} + {{- if (or (and (ne (.Values.connectInject.metrics.defaultEnabled | toString) "-") .Values.connectInject.metrics.defaultEnabled) (and (eq (.Values.connectInject.metrics.defaultEnabled | toString) "-") .Values.global.metrics.enabled)) }} + -default-enable-metrics=true \ + {{- else }} + -default-enable-metrics=false \ + {{- end }} + -enable-gateway-metrics={{ .Values.global.metrics.enableGatewayMetrics }} \ + -default-enable-metrics-merging={{ .Values.connectInject.metrics.defaultEnableMerging }} \ + -default-merged-metrics-port={{ .Values.connectInject.metrics.defaultMergedMetricsPort }} \ + -default-prometheus-scrape-port={{ .Values.connectInject.metrics.defaultPrometheusScrapePort }} \ + -default-prometheus-scrape-path="{{ .Values.connectInject.metrics.defaultPrometheusScrapePath }}" \ + {{- if .Values.connectInject.envoyExtraArgs }} + -envoy-extra-args="{{ .Values.connectInject.envoyExtraArgs }}" \ + {{- end }} + {{- if .Values.connectInject.overrideAuthMethodName }} + -acl-auth-method="{{ .Values.connectInject.overrideAuthMethodName }}" \ + {{- else if .Values.global.acls.manageSystemACLs }} + -acl-auth-method="{{ template "consul.fullname" . }}-k8s-auth-method" \ + {{- end }} + {{- range $value := .Values.connectInject.k8sAllowNamespaces }} + -allow-k8s-namespace="{{ $value }}" \ + {{- end }} + {{- range $value := .Values.connectInject.k8sDenyNamespaces }} + -deny-k8s-namespace="{{ $value }}" \ + {{- end }} + {{- if .Values.global.adminPartitions.enabled }} + -enable-partitions=true \ + {{- end }} + {{- if .Values.global.enableConsulNamespaces }} + -enable-namespaces=true \ + {{- if .Values.connectInject.consulNamespaces.consulDestinationNamespace }} + -consul-destination-namespace={{ .Values.connectInject.consulNamespaces.consulDestinationNamespace }} \ + {{- end }} + {{- if and .Values.global.enableConsulNamespaces .Values.connectInject.consulNamespaces.mirroringK8S }} + -enable-k8s-namespace-mirroring=true \ + {{- if .Values.connectInject.consulNamespaces.mirroringK8SPrefix }} + -k8s-namespace-mirroring-prefix={{ .Values.connectInject.consulNamespaces.mirroringK8SPrefix }} \ + {{- end }} + {{- end }} + {{- if .Values.global.acls.manageSystemACLs }} + -consul-cross-namespace-acl-policy=cross-namespace-policy \ + {{- end }} + {{- end }} + {{- if and .Values.global.secretsBackend.vault.enabled .Values.global.secretsBackend.vault.connectInject.tlsCert.secretName }} + -tls-cert-dir=/vault/secrets/connect-injector/certs \ + -enable-webhook-ca-update \ + {{- else }} + -tls-cert-dir=/etc/connect-injector/certs \ + {{- end }} + {{- $resources := .Values.connectInject.sidecarProxy.resources }} + {{- /* kindIs is used here to differentiate between null and 0 */}} + {{- if not (kindIs "invalid" $resources.limits.memory) }} + -default-sidecar-proxy-memory-limit={{ $resources.limits.memory }} \ + {{- end }} + {{- if not (kindIs "invalid" $resources.requests.memory) }} + -default-sidecar-proxy-memory-request={{ $resources.requests.memory }} \ + {{- end }} + {{- if not (kindIs "invalid" $resources.limits.cpu) }} + -default-sidecar-proxy-cpu-limit={{ $resources.limits.cpu }} \ + {{- end }} + {{- if not (kindIs "invalid" $resources.requests.cpu) }} + -default-sidecar-proxy-cpu-request={{ $resources.requests.cpu }} \ + {{- end }} + -default-envoy-proxy-concurrency={{ .Values.connectInject.sidecarProxy.concurrency }} \ + {{- if .Values.connectInject.sidecarProxy.lifecycle.defaultEnabled }} + -default-enable-sidecar-proxy-lifecycle=true \ + {{- else }} + -default-enable-sidecar-proxy-lifecycle=false \ + {{- end }} + {{- if .Values.connectInject.sidecarProxy.lifecycle.defaultEnableShutdownDrainListeners }} + -default-enable-sidecar-proxy-lifecycle-shutdown-drain-listeners=true \ + {{- else }} + -default-enable-sidecar-proxy-lifecycle-shutdown-drain-listeners=false \ + {{- end }} + -default-sidecar-proxy-lifecycle-shutdown-grace-period-seconds={{ .Values.connectInject.sidecarProxy.lifecycle.defaultShutdownGracePeriodSeconds }} \ + -default-sidecar-proxy-lifecycle-startup-grace-period-seconds={{ .Values.connectInject.sidecarProxy.lifecycle.defaultStartupGracePeriodSeconds }} \ + -default-sidecar-proxy-lifecycle-graceful-port={{ .Values.connectInject.sidecarProxy.lifecycle.defaultGracefulPort }} \ + -default-sidecar-proxy-lifecycle-graceful-shutdown-path="{{ .Values.connectInject.sidecarProxy.lifecycle.defaultGracefulShutdownPath }}" \ + -default-sidecar-proxy-lifecycle-graceful-startup-path="{{ .Values.connectInject.sidecarProxy.lifecycle.defaultGracefulStartupPath }}" \ + -default-sidecar-proxy-startup-failure-seconds={{ .Values.connectInject.sidecarProxy.defaultStartupFailureSeconds }} \ + -default-sidecar-proxy-liveness-failure-seconds={{ .Values.connectInject.sidecarProxy.defaultLivenessFailureSeconds }} \ + {{- if .Values.connectInject.initContainer }} + {{- $initResources := .Values.connectInject.initContainer.resources }} + {{- if not (kindIs "invalid" $initResources.limits.memory) }} + -init-container-memory-limit={{ $initResources.limits.memory }} \ + {{- end }} + {{- if not (kindIs "invalid" $initResources.requests.memory) }} + -init-container-memory-request={{ $initResources.requests.memory }} \ + {{- end }} + {{- if not (kindIs "invalid" $initResources.limits.cpu) }} + -init-container-cpu-limit={{ $initResources.limits.cpu }} \ + {{- end }} + {{- if not (kindIs "invalid" $initResources.requests.cpu) }} + -init-container-cpu-request={{ $initResources.requests.cpu }} \ + {{- end }} + {{- end }} + + {{- if .Values.global.cloud.enabled }} + -tls-server-name=server.{{ .Values.global.datacenter}}.{{ .Values.global.domain}} \ + {{- end }} + {{- if and .Values.global.tls.enabled .Values.global.tls.enableAutoEncrypt }} + -enable-auto-encrypt \ + {{- end }} + -enable-telemetry-collector={{ .Values.global.metrics.enableTelemetryCollector}} \ + startupProbe: + httpGet: + path: /readyz/ready + port: 9445 + scheme: HTTP + initialDelaySeconds: 30 + failureThreshold: 15 + periodSeconds: 2 + timeoutSeconds: 5 + livenessProbe: + httpGet: + path: /readyz/ready + port: 9445 + scheme: HTTP + failureThreshold: 2 + initialDelaySeconds: 1 + successThreshold: 1 + timeoutSeconds: 5 + readinessProbe: + httpGet: + path: /readyz/ready + port: 9445 + scheme: HTTP + failureThreshold: 2 + initialDelaySeconds: 2 + successThreshold: 1 + timeoutSeconds: 5 + volumeMounts: + {{- if not (and .Values.global.secretsBackend.vault.enabled .Values.global.secretsBackend.vault.connectInject.tlsCert.secretName) }} + - name: certs + mountPath: /etc/connect-injector/certs + readOnly: true + {{- end }} + {{- if and .Values.global.tls.enabled (not (or (and .Values.externalServers.enabled .Values.externalServers.useSystemRoots) .Values.global.secretsBackend.vault.enabled))}} + - name: consul-ca-cert + mountPath: /consul/tls/ca + readOnly: true + {{- end }} + {{- with .Values.connectInject.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + volumes: + {{- if not (and .Values.global.secretsBackend.vault.enabled .Values.global.secretsBackend.vault.connectInject.tlsCert.secretName) }} + - name: certs + secret: + defaultMode: 420 + secretName: {{ template "consul.fullname" . }}-connect-inject-webhook-cert + {{- end }} + {{- if .Values.global.tls.enabled }} + {{- if not (or (and .Values.externalServers.enabled .Values.externalServers.useSystemRoots) .Values.global.secretsBackend.vault.enabled) }} + - name: consul-ca-cert + secret: + {{- if .Values.global.tls.caCert.secretName }} + secretName: {{ .Values.global.tls.caCert.secretName }} + {{- else }} + secretName: {{ template "consul.fullname" . }}-ca-cert + {{- end }} + items: + - key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }} + path: tls.crt + {{- end }} + {{- end }} + {{- if .Values.connectInject.priorityClassName }} + priorityClassName: {{ .Values.connectInject.priorityClassName | quote }} + {{- end }} + {{- if .Values.connectInject.nodeSelector }} + nodeSelector: + {{ tpl .Values.connectInject.nodeSelector . | indent 8 | trim }} + {{- end }} + {{- if .Values.connectInject.affinity }} + affinity: + {{ tpl .Values.connectInject.affinity . | indent 8 | trim }} + {{- end }} + {{- if .Values.connectInject.tolerations }} + tolerations: + {{ tpl .Values.connectInject.tolerations . | indent 8 | trim }} + {{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/connect-inject-leader-election-role.yaml b/kubernetes-vault/consul/templates/connect-inject-leader-election-role.yaml new file mode 100644 index 0000000..703aaff --- /dev/null +++ b/kubernetes-vault/consul/templates/connect-inject-leader-election-role.yaml @@ -0,0 +1,41 @@ +{{- if or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled) }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "consul.fullname" . }}-connect-inject-leader-election + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: connect-injector +rules: +- apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - "" + resources: + - configmaps/status + verbs: + - get + - update + - patch +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch +{{- end }} diff --git a/kubernetes-vault/consul/templates/connect-inject-leader-election-rolebinding.yaml b/kubernetes-vault/consul/templates/connect-inject-leader-election-rolebinding.yaml new file mode 100644 index 0000000..9a27d3c --- /dev/null +++ b/kubernetes-vault/consul/templates/connect-inject-leader-election-rolebinding.yaml @@ -0,0 +1,21 @@ +{{- if or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled) }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "consul.fullname" . }}-connect-inject-leader-election + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: connect-injector +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "consul.fullname" . }}-connect-inject-leader-election +subjects: +- kind: ServiceAccount + name: {{ template "consul.fullname" . }}-connect-injector + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/connect-inject-mutatingwebhookconfiguration.yaml b/kubernetes-vault/consul/templates/connect-inject-mutatingwebhookconfiguration.yaml new file mode 100644 index 0000000..e65c386 --- /dev/null +++ b/kubernetes-vault/consul/templates/connect-inject-mutatingwebhookconfiguration.yaml @@ -0,0 +1,381 @@ +{{- if (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled)) }} +# The MutatingWebhookConfiguration to enable the Connect injector. +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + name: {{ template "consul.fullname" . }}-connect-injector + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: connect-injector +webhooks: +- clientConfig: + service: + name: {{ template "consul.fullname" . }}-connect-injector + namespace: {{ .Release.Namespace }} + path: /mutate-v1alpha1-proxydefaults + failurePolicy: Fail + admissionReviewVersions: + - "v1beta1" + - "v1" + name: mutate-proxydefaults.consul.hashicorp.com + rules: + - apiGroups: + - consul.hashicorp.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - proxydefaults + sideEffects: None +- clientConfig: + service: + name: {{ template "consul.fullname" . }}-connect-injector + namespace: {{ .Release.Namespace }} + path: /mutate-v1alpha1-mesh + failurePolicy: Fail + admissionReviewVersions: + - "v1beta1" + - "v1" + name: mutate-mesh.consul.hashicorp.com + rules: + - apiGroups: + - consul.hashicorp.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - meshes + sideEffects: None +- clientConfig: + service: + name: {{ template "consul.fullname" . }}-connect-injector + namespace: {{ .Release.Namespace }} + path: /mutate-v1alpha1-servicedefaults + failurePolicy: Fail + admissionReviewVersions: + - "v1beta1" + - "v1" + name: mutate-servicedefaults.consul.hashicorp.com + rules: + - apiGroups: + - consul.hashicorp.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - servicedefaults + sideEffects: None +- clientConfig: + service: + name: {{ template "consul.fullname" . }}-connect-injector + namespace: {{ .Release.Namespace }} + path: /mutate-v1alpha1-serviceresolver + failurePolicy: Fail + admissionReviewVersions: + - "v1beta1" + - "v1" + name: mutate-serviceresolver.consul.hashicorp.com + rules: + - apiGroups: + - consul.hashicorp.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - serviceresolvers + sideEffects: None +- clientConfig: + service: + name: {{ template "consul.fullname" . }}-connect-injector + namespace: {{ .Release.Namespace }} + path: /mutate-v1alpha1-servicerouter + failurePolicy: Fail + admissionReviewVersions: + - "v1beta1" + - "v1" + name: mutate-servicerouter.consul.hashicorp.com + rules: + - apiGroups: + - consul.hashicorp.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - servicerouters + sideEffects: None +- clientConfig: + service: + name: {{ template "consul.fullname" . }}-connect-injector + namespace: {{ .Release.Namespace }} + path: /mutate-v1alpha1-servicesplitter + failurePolicy: Fail + admissionReviewVersions: + - "v1beta1" + - "v1" + name: mutate-servicesplitter.consul.hashicorp.com + rules: + - apiGroups: + - consul.hashicorp.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - servicesplitters + sideEffects: None +- clientConfig: + service: + name: {{ template "consul.fullname" . }}-connect-injector + namespace: {{ .Release.Namespace }} + path: /mutate-v1alpha1-serviceintentions + failurePolicy: Fail + admissionReviewVersions: + - "v1beta1" + - "v1" + name: mutate-serviceintentions.consul.hashicorp.com + rules: + - apiGroups: + - consul.hashicorp.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - serviceintentions + sideEffects: None +- clientConfig: + service: + name: {{ template "consul.fullname" . }}-connect-injector + namespace: {{ .Release.Namespace }} + path: /mutate-v1alpha1-ingressgateway + failurePolicy: Fail + admissionReviewVersions: + - "v1beta1" + - "v1" + name: mutate-ingressgateway.consul.hashicorp.com + rules: + - apiGroups: + - consul.hashicorp.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - ingressgateways + sideEffects: None +- clientConfig: + service: + name: {{ template "consul.fullname" . }}-connect-injector + namespace: {{ .Release.Namespace }} + path: /mutate-v1alpha1-terminatinggateway + failurePolicy: Fail + admissionReviewVersions: + - "v1beta1" + - "v1" + name: mutate-terminatinggateway.consul.hashicorp.com + rules: + - apiGroups: + - consul.hashicorp.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - terminatinggateways + sideEffects: None +- clientConfig: + service: + name: {{ template "consul.fullname" . }}-connect-injector + namespace: {{ .Release.Namespace }} + path: /mutate-v1alpha1-exportedservices + failurePolicy: Fail + admissionReviewVersions: + - "v1beta1" + - "v1" + name: mutate-exportedservices.consul.hashicorp.com + rules: + - apiGroups: + - consul.hashicorp.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - exportedservices + sideEffects: None +- clientConfig: + service: + name: {{ template "consul.fullname" . }}-connect-injector + namespace: {{ .Release.Namespace }} + path: /mutate-v1alpha1-controlplanerequestlimits + failurePolicy: Fail + admissionReviewVersions: + - "v1beta1" + - "v1" + name: mutate-controlplanerequestlimit.consul.hashicorp.com + rules: + - apiGroups: + - consul.hashicorp.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - controlplanerequestlimits + sideEffects: None +- name: {{ template "consul.fullname" . }}-connect-injector.consul.hashicorp.com + # The webhook will fail scheduling all pods that are not part of consul if all replicas of the webhook are unhealthy. + objectSelector: + matchExpressions: + - key: app + operator: NotIn + values: [ {{ template "consul.name" . }} ] + failurePolicy: {{ .Values.connectInject.failurePolicy }} + sideEffects: None + admissionReviewVersions: + - "v1beta1" + - "v1" + clientConfig: + service: + name: {{ template "consul.fullname" . }}-connect-injector + namespace: {{ .Release.Namespace }} + path: "/mutate" + rules: + - operations: [ "CREATE" ] + apiGroups: [ "" ] + apiVersions: [ "v1" ] + resources: [ "pods" ] +{{- if .Values.connectInject.namespaceSelector }} + namespaceSelector: +{{ tpl .Values.connectInject.namespaceSelector . | indent 6 }} +{{- end }} +{{- if .Values.global.peering.enabled }} +- name: {{ template "consul.fullname" . }}-mutate-peeringacceptors.consul.hashicorp.com + clientConfig: + service: + name: {{ template "consul.fullname" . }}-connect-injector + namespace: {{ .Release.Namespace }} + path: "/mutate-v1alpha1-peeringacceptors" + rules: + - apiGroups: + - consul.hashicorp.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - peeringacceptors + failurePolicy: Fail + sideEffects: None + admissionReviewVersions: + - "v1beta1" + - "v1" +- name: {{ template "consul.fullname" . }}-mutate-peeringdialers.consul.hashicorp.com + clientConfig: + service: + name: {{ template "consul.fullname" . }}-connect-injector + namespace: {{ .Release.Namespace }} + path: "/mutate-v1alpha1-peeringdialers" + rules: + - apiGroups: + - consul.hashicorp.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - peeringdialers + failurePolicy: Fail + sideEffects: None + admissionReviewVersions: + - "v1beta1" + - "v1" +- admissionReviewVersions: + - v1beta1 + - v1 + clientConfig: + service: + name: {{ template "consul.fullname" . }}-connect-injector + namespace: {{ .Release.Namespace }} + path: /mutate-v1alpha1-samenessgroup + failurePolicy: Fail + name: mutate-samenessgroup.consul.hashicorp.com + rules: + - apiGroups: + - consul.hashicorp.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - samenessgroups + sideEffects: None +{{- if (mustHas "resource-apis" .Values.global.experiments) }} +- admissionReviewVersions: + - v1beta1 + - v1 + clientConfig: + service: + name: {{ template "consul.fullname" . }}-connect-injector + namespace: {{ .Release.Namespace }} + path: /mutate-v2beta1-trafficpermissions + failurePolicy: Fail + name: mutate-trafficpermissions.auth.consul.hashicorp.com + rules: + - apiGroups: + - auth.consul.hashicorp.com + apiVersions: + - v2beta1 + operations: + - CREATE + - UPDATE + resources: + - trafficpermissions + sideEffects: None +{{- end }} +{{- end }} +- admissionReviewVersions: + - v1beta1 + - v1 + clientConfig: + service: + name: {{ template "consul.fullname" . }}-connect-injector + namespace: {{ .Release.Namespace }} + path: /mutate-v1alpha1-jwtprovider + failurePolicy: Fail + name: mutate-jwtprovider.consul.hashicorp.com + rules: + - apiGroups: + - consul.hashicorp.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - jwtproviders + sideEffects: None +{{- end }} diff --git a/kubernetes-vault/consul/templates/connect-inject-podsecuritypolicy.yaml b/kubernetes-vault/consul/templates/connect-inject-podsecuritypolicy.yaml new file mode 100644 index 0000000..0fafef7 --- /dev/null +++ b/kubernetes-vault/consul/templates/connect-inject-podsecuritypolicy.yaml @@ -0,0 +1,40 @@ +{{- if (and .Values.global.enablePodSecurityPolicies (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled))) }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "consul.fullname" . }}-connect-injector + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: connect-injector +spec: + privileged: false + # Required to prevent escalations to root. + allowPrivilegeEscalation: false + # This is redundant with non-root + disallow privilege escalation, + # but we can provide it for defense in depth. + requiredDropCapabilities: + - ALL + # Allow core volume types. + volumes: + - 'configMap' + - 'emptyDir' + - 'projected' + - 'secret' + - 'downwardAPI' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' + readOnlyRootFilesystem: false +{{- end }} diff --git a/kubernetes-vault/consul/templates/connect-inject-service.yaml b/kubernetes-vault/consul/templates/connect-inject-service.yaml new file mode 100644 index 0000000..b0284af --- /dev/null +++ b/kubernetes-vault/consul/templates/connect-inject-service.yaml @@ -0,0 +1,23 @@ +{{- if (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled)) }} +# The service for the Connect sidecar injector +apiVersion: v1 +kind: Service +metadata: + name: {{ template "consul.fullname" . }}-connect-injector + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: connect-injector +spec: + ports: + - port: 443 + targetPort: 8080 + selector: + app: {{ template "consul.name" . }} + release: "{{ .Release.Name }}" + component: connect-injector +{{- end }} + diff --git a/kubernetes-vault/consul/templates/connect-inject-serviceaccount.yaml b/kubernetes-vault/consul/templates/connect-inject-serviceaccount.yaml new file mode 100644 index 0000000..ea2352c --- /dev/null +++ b/kubernetes-vault/consul/templates/connect-inject-serviceaccount.yaml @@ -0,0 +1,23 @@ +{{- if or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled) }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "consul.fullname" . }}-connect-injector + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: connect-injector + {{- if .Values.connectInject.serviceAccount.annotations }} + annotations: + {{ tpl .Values.connectInject.serviceAccount.annotations . | nindent 4 | trim }} + {{- end }} +{{- with .Values.global.imagePullSecrets }} +imagePullSecrets: +{{- range . }} +- name: {{ .name }} +{{- end }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/connect-inject-validatingwebhookconfiguration.yaml b/kubernetes-vault/consul/templates/connect-inject-validatingwebhookconfiguration.yaml new file mode 100644 index 0000000..92068bb --- /dev/null +++ b/kubernetes-vault/consul/templates/connect-inject-validatingwebhookconfiguration.yaml @@ -0,0 +1,47 @@ +{{- if (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled)) }} +# The ValidatingWebhookConfiguration to enable the Connect injector. +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: {{ template "consul.fullname" . }}-connect-injector + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: connect-injector +webhooks: +- name: validate-gatewaypolicy.consul.hashicorp.com + matchPolicy: Equivalent + rules: + - operations: [ "CREATE" , "UPDATE" ] + apiGroups: [ "consul.hashicorp.com" ] + apiVersions: [ "v1alpha1" ] + resources: [ "gatewaypolicies" ] + failurePolicy: Fail + sideEffects: None + admissionReviewVersions: + - v1 + clientConfig: + service: + name: {{ template "consul.fullname" . }}-connect-injector + namespace: {{ .Release.Namespace }} + path: /validate-v1alpha1-gatewaypolicy +- name: validate-registration.consul.hashicorp.com + matchPolicy: Equivalent + rules: + - operations: [ "CREATE" , "UPDATE" ] + apiGroups: [ "consul.hashicorp.com" ] + apiVersions: [ "v1alpha1" ] + resources: [ "registrations" ] + failurePolicy: Fail + sideEffects: None + admissionReviewVersions: + - v1 + clientConfig: + service: + name: {{ template "consul.fullname" . }}-connect-injector + namespace: {{ .Release.Namespace }} + path: /validate-v1alpha1-registration +{{- end }} diff --git a/kubernetes-vault/consul/templates/connect-injector-disruptionbudget.yaml b/kubernetes-vault/consul/templates/connect-injector-disruptionbudget.yaml new file mode 100644 index 0000000..9b9cf2e --- /dev/null +++ b/kubernetes-vault/consul/templates/connect-injector-disruptionbudget.yaml @@ -0,0 +1,30 @@ +{{- if (and .Values.connectInject.disruptionBudget.enabled (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled))) }} +# PodDisruptionBudget to prevent degrading the connectInject cluster through +# voluntary cluster changes. +{{- if .Capabilities.APIVersions.Has "policy/v1/PodDisruptionBudget" }} +apiVersion: policy/v1 +{{- else }} +apiVersion: policy/v1beta1 +{{- end }} +kind: PodDisruptionBudget +metadata: + name: {{ template "consul.fullname" . }}-connect-injector + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: connect-injector +spec: + {{- if .Values.connectInject.disruptionBudget.minAvailable }} + minAvailable: {{ .Values.connectInject.disruptionBudget.minAvailable }} + {{- else }} + maxUnavailable: {{ template "consul.pdb.connectInject.maxUnavailable" . }} + {{- end }} + selector: + matchLabels: + app: {{ template "consul.name" . }} + release: "{{ .Release.Name }}" + component: connect-injector +{{- end }} diff --git a/kubernetes-vault/consul/templates/crd-apigateways.yaml b/kubernetes-vault/consul/templates/crd-apigateways.yaml new file mode 100644 index 0000000..c790c6d --- /dev/null +++ b/kubernetes-vault/consul/templates/crd-apigateways.yaml @@ -0,0 +1,317 @@ +{{- if .Values.connectInject.enabled }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: crd + name: apigateways.mesh.consul.hashicorp.com +spec: + group: mesh.consul.hashicorp.com + names: + kind: APIGateway + listKind: APIGatewayList + plural: apigateways + singular: apigateway + scope: Cluster + versions: + - additionalPrinterColumns: + - description: The sync status of the resource with Consul + jsonPath: .status.conditions[?(@.type=="Synced")].status + name: Synced + type: string + - description: The last successful synced time of the resource with Consul + jsonPath: .status.lastSyncedTime + name: Last Synced + type: date + - description: The age of the resource + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v2beta1 + schema: + openAPIV3Schema: + description: APIGateway is the Schema for the API Gateway + 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: + gatewayClassName: + description: GatewayClassName is the name of the GatewayClass used + by the APIGateway + type: string + listeners: + items: + properties: + hostname: + description: |- + Hostname is the host name that a listener should be bound to, if + unspecified, the listener accepts requests for all hostnames. + type: string + name: + description: |- + Name is the name of the listener in a given gateway. This must be + unique within a gateway. + type: string + port: + format: int32 + maximum: 65535 + minimum: 0 + type: integer + protocol: + description: |- + Protocol is the protocol that a listener should use, it must + either be "http" or "tcp" + type: string + tls: + description: TLS is the TLS settings for the listener. + properties: + certificates: + description: |- + Certificates is a set of references to certificates + that a gateway listener uses for TLS termination. + items: + description: |- + Reference identifies which resource a condition relates to, when it is not + the core resource itself. + properties: + name: + description: Name is the user-given name of the resource + (e.g. the "billing" service). + type: string + section: + description: Section identifies which part of the + resource the condition relates to. + type: string + tenancy: + description: |- + Tenancy identifies the tenancy units (i.e. partition, namespace) in which + the resource resides. + properties: + namespace: + description: |- + Namespace further isolates resources within a partition. + https://developer.hashicorp.com/consul/docs/enterprise/namespaces + + + When using the List and WatchList endpoints, provide the wildcard value "*" + to list resources across all namespaces. + type: string + partition: + description: |- + Partition is the topmost administrative boundary within a cluster. + https://developer.hashicorp.com/consul/docs/enterprise/admin-partitions + + + When using the List and WatchList endpoints, provide the wildcard value "*" + to list resources across all partitions. + type: string + type: object + type: + description: Type identifies the resource's type. + properties: + group: + description: |- + Group describes the area of functionality to which this resource type + relates (e.g. "catalog", "authorization"). + type: string + groupVersion: + description: |- + GroupVersion is incremented when sweeping or backward-incompatible changes + are made to the group's resource types. + type: string + kind: + description: Kind identifies the specific resource + type within the group. + type: string + type: object + type: object + type: array + tlsParameters: + description: TLSParameters contains optional configuration + for running TLS termination. + properties: + cipherSuites: + items: + enum: + - TLS_CIPHER_SUITE_ECDHE_ECDSA_AES128_GCM_SHA256 + - TLS_CIPHER_SUITE_AES256_SHA + - TLS_CIPHER_SUITE_ECDHE_ECDSA_CHACHA20_POLY1305 + - TLS_CIPHER_SUITE_ECDHE_RSA_AES128_GCM_SHA256 + - TLS_CIPHER_SUITE_ECDHE_RSA_CHACHA20_POLY1305 + - TLS_CIPHER_SUITE_ECDHE_ECDSA_AES128_SHA + - TLS_CIPHER_SUITE_ECDHE_RSA_AES128_SHA + - TLS_CIPHER_SUITE_AES128_GCM_SHA256 + - TLS_CIPHER_SUITE_AES128_SHA + - TLS_CIPHER_SUITE_ECDHE_ECDSA_AES256_GCM_SHA384 + - TLS_CIPHER_SUITE_ECDHE_RSA_AES256_GCM_SHA384 + - TLS_CIPHER_SUITE_ECDHE_ECDSA_AES256_SHA + - TLS_CIPHER_SUITE_ECDHE_RSA_AES256_SHA + - TLS_CIPHER_SUITE_AES256_GCM_SHA384 + format: int32 + type: string + type: array + maxVersion: + enum: + - TLS_VERSION_AUTO + - TLS_VERSION_1_0 + - TLS_VERSION_1_1 + - TLS_VERSION_1_2 + - TLS_VERSION_1_3 + - TLS_VERSION_INVALID + - TLS_VERSION_UNSPECIFIED + format: int32 + type: string + minVersion: + enum: + - TLS_VERSION_AUTO + - TLS_VERSION_1_0 + - TLS_VERSION_1_1 + - TLS_VERSION_1_2 + - TLS_VERSION_1_3 + - TLS_VERSION_INVALID + - TLS_VERSION_UNSPECIFIED + format: int32 + type: string + type: object + type: object + type: object + minItems: 1 + type: array + type: object + status: + properties: + addresses: + items: + properties: + type: + default: IPAddress + type: string + value: + type: string + required: + - type + - value + type: object + type: array + listeners: + items: + properties: + attachedRoutes: + format: int32 + type: integer + name: + type: string + status: + properties: + conditions: + description: Conditions indicate the latest available observations + of a resource's current state. + items: + description: |- + Conditions define a readiness condition for a Consul resource. + See: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties + properties: + lastTransitionTime: + description: LastTransitionTime is the 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 condition. + type: string + required: + - status + - type + type: object + type: array + lastSyncedTime: + description: LastSyncedTime is the last time the resource + successfully synced with Consul. + format: date-time + type: string + type: object + required: + - attachedRoutes + - name + type: object + type: array + status: + properties: + conditions: + description: Conditions indicate the latest available observations + of a resource's current state. + items: + description: |- + Conditions define a readiness condition for a Consul resource. + See: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties + properties: + lastTransitionTime: + description: LastTransitionTime is the 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 condition. + type: string + required: + - status + - type + type: object + type: array + lastSyncedTime: + description: LastSyncedTime is the last time the resource successfully + synced with Consul. + format: date-time + type: string + type: object + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- end }} diff --git a/kubernetes-vault/consul/templates/crd-controlplanerequestlimits.yaml b/kubernetes-vault/consul/templates/crd-controlplanerequestlimits.yaml new file mode 100644 index 0000000..4e11ceb --- /dev/null +++ b/kubernetes-vault/consul/templates/crd-controlplanerequestlimits.yaml @@ -0,0 +1,201 @@ +{{- if .Values.connectInject.enabled }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: crd + name: controlplanerequestlimits.consul.hashicorp.com +spec: + group: consul.hashicorp.com + names: + kind: ControlPlaneRequestLimit + listKind: ControlPlaneRequestLimitList + plural: controlplanerequestlimits + singular: controlplanerequestlimit + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The sync status of the resource with Consul + jsonPath: .status.conditions[?(@.type=="Synced")].status + name: Synced + type: string + - description: The age of the resource + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: ControlPlaneRequestLimit is the Schema for the controlplanerequestlimits + 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: ControlPlaneRequestLimitSpec defines the desired state of + ControlPlaneRequestLimit. + properties: + acl: + properties: + readRate: + type: number + writeRate: + type: number + type: object + catalog: + properties: + readRate: + type: number + writeRate: + type: number + type: object + configEntry: + properties: + readRate: + type: number + writeRate: + type: number + type: object + connectCA: + properties: + readRate: + type: number + writeRate: + type: number + type: object + coordinate: + properties: + readRate: + type: number + writeRate: + type: number + type: object + discoveryChain: + properties: + readRate: + type: number + writeRate: + type: number + type: object + health: + properties: + readRate: + type: number + writeRate: + type: number + type: object + intention: + properties: + readRate: + type: number + writeRate: + type: number + type: object + kv: + properties: + readRate: + type: number + writeRate: + type: number + type: object + mode: + type: string + preparedQuery: + properties: + readRate: + type: number + writeRate: + type: number + type: object + readRate: + type: number + session: + properties: + readRate: + type: number + writeRate: + type: number + type: object + tenancy: + properties: + readRate: + type: number + writeRate: + type: number + type: object + txn: + properties: + readRate: + type: number + writeRate: + type: number + type: object + writeRate: + type: number + type: object + status: + properties: + conditions: + description: Conditions indicate the latest available observations + of a resource's current state. + items: + description: |- + Conditions define a readiness condition for a Consul resource. + See: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties + properties: + lastTransitionTime: + description: LastTransitionTime is the 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 condition. + type: string + required: + - status + - type + type: object + type: array + lastSyncedTime: + description: LastSyncedTime is the last time the resource successfully + synced with Consul. + format: date-time + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- end }} diff --git a/kubernetes-vault/consul/templates/crd-exportedservices-v1.yaml b/kubernetes-vault/consul/templates/crd-exportedservices-v1.yaml new file mode 100644 index 0000000..a7fbd87 --- /dev/null +++ b/kubernetes-vault/consul/templates/crd-exportedservices-v1.yaml @@ -0,0 +1,147 @@ +{{- if .Values.connectInject.enabled }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: crd + name: exportedservices.consul.hashicorp.com +spec: + group: consul.hashicorp.com + names: + kind: ExportedServices + listKind: ExportedServicesList + plural: exportedservices + shortNames: + - exported-services + singular: exportedservices + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The sync status of the resource with Consul + jsonPath: .status.conditions[?(@.type=="Synced")].status + name: Synced + type: string + - description: The last successful synced time of the resource with Consul + jsonPath: .status.lastSyncedTime + name: Last Synced + type: date + - description: The age of the resource + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: ExportedServices is the Schema for the exportedservices 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: ExportedServicesSpec defines the desired state of ExportedServices. + properties: + services: + description: |- + Services is a list of services to be exported and the list of partitions + to expose them to. + items: + description: |- + ExportedService manages the exporting of a service in the local partition to + other partitions. + properties: + consumers: + description: Consumers is a list of downstream consumers of + the service to be exported. + items: + description: ServiceConsumer represents a downstream consumer + of the service to be exported. + properties: + partition: + description: Partition is the admin partition to export + the service to. + type: string + peer: + description: Peer is the name of the peer to export the + service to. + type: string + samenessGroup: + description: SamenessGroup is the name of the sameness + group to export the service to. + type: string + type: object + type: array + name: + description: Name is the name of the service to be exported. + type: string + namespace: + description: Namespace is the namespace to export the service + from. + type: string + type: object + type: array + type: object + status: + properties: + conditions: + description: Conditions indicate the latest available observations + of a resource's current state. + items: + description: |- + Conditions define a readiness condition for a Consul resource. + See: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties + properties: + lastTransitionTime: + description: LastTransitionTime is the 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 condition. + type: string + required: + - status + - type + type: object + type: array + lastSyncedTime: + description: LastSyncedTime is the last time the resource successfully + synced with Consul. + format: date-time + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- end }} diff --git a/kubernetes-vault/consul/templates/crd-exportedservices.yaml b/kubernetes-vault/consul/templates/crd-exportedservices.yaml new file mode 100644 index 0000000..4b9beb6 --- /dev/null +++ b/kubernetes-vault/consul/templates/crd-exportedservices.yaml @@ -0,0 +1,114 @@ +{{- if .Values.connectInject.enabled }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: crd + name: exportedservices.multicluster.consul.hashicorp.com +spec: + group: multicluster.consul.hashicorp.com + names: + kind: ExportedServices + listKind: ExportedServicesList + plural: exportedservices + singular: exportedservices + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The sync status of the resource with Consul + jsonPath: .status.conditions[?(@.type=="Synced")].status + name: Synced + type: string + - description: The last successful synced time of the resource with Consul + jsonPath: .status.lastSyncedTime + name: Last Synced + type: date + - description: The age of the resource + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v2 + schema: + openAPIV3Schema: + description: ExportedServices is the Schema for the Exported Services API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + properties: + consumers: + items: + type: object + x-kubernetes-preserve-unknown-fields: true + type: array + services: + items: + type: string + type: array + type: object + status: + properties: + conditions: + description: Conditions indicate the latest available observations + of a resource's current state. + items: + description: |- + Conditions define a readiness condition for a Consul resource. + See: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties + properties: + lastTransitionTime: + description: LastTransitionTime is the 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 condition. + type: string + required: + - status + - type + type: object + type: array + lastSyncedTime: + description: LastSyncedTime is the last time the resource successfully + synced with Consul. + format: date-time + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- end }} diff --git a/kubernetes-vault/consul/templates/crd-gatewayclassconfigs-v1.yaml b/kubernetes-vault/consul/templates/crd-gatewayclassconfigs-v1.yaml new file mode 100644 index 0000000..2db954b --- /dev/null +++ b/kubernetes-vault/consul/templates/crd-gatewayclassconfigs-v1.yaml @@ -0,0 +1,232 @@ +{{- if .Values.connectInject.enabled }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: crd + name: gatewayclassconfigs.consul.hashicorp.com +spec: + group: consul.hashicorp.com + names: + kind: GatewayClassConfig + listKind: GatewayClassConfigList + plural: gatewayclassconfigs + singular: gatewayclassconfig + scope: Cluster + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: GatewayClassConfig defines the values that may be set on a GatewayClass + for Consul API Gateway. + 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 GatewayClassConfig. + properties: + copyAnnotations: + description: Annotation Information to copy to services or deployments + properties: + service: + description: List of annotations to copy to the gateway service. + items: + type: string + type: array + type: object + deployment: + description: Deployment defines the deployment configuration for the + gateway. + properties: + defaultInstances: + default: 1 + description: Number of gateway instances that should be deployed + by default + format: int32 + maximum: 8 + minimum: 1 + type: integer + maxInstances: + default: 8 + description: Max allowed number of gateway instances + format: int32 + maximum: 8 + minimum: 1 + type: integer + minInstances: + default: 1 + description: Minimum allowed number of gateway instances + format: int32 + maximum: 8 + minimum: 1 + type: integer + resources: + description: Resources defines the resource requirements for the + gateway. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + type: object + mapPrivilegedContainerPorts: + description: The value to add to privileged ports ( ports < 1024) + for gateway containers + format: int32 + type: integer + metrics: + description: Metrics defines how to configure the metrics for a gateway. + properties: + enabled: + description: |- + Enable metrics for this class of gateways. If unspecified, will inherit + behavior from the global Helm configuration. + type: boolean + path: + description: The path used for metrics. + type: string + port: + description: The port used for metrics. + format: int32 + maximum: 65535 + minimum: 1024 + type: integer + type: object + nodeSelector: + additionalProperties: + type: string + description: |- + NodeSelector is a selector which must be true for the pod to fit on a node. + Selector which must match a node's labels for the pod to be scheduled on that node. + More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + type: object + openshiftSCCName: + description: The name of the OpenShift SecurityContextConstraints + resource for this gateway class to use. + type: string + podSecurityPolicy: + description: The name of an existing Kubernetes PodSecurityPolicy + to bind to the managed ServiceAccount if ACLs are managed. + type: string + serviceType: + description: Service Type string describes ingress methods for a service + enum: + - ClusterIP + - NodePort + - LoadBalancer + type: string + tolerations: + description: |- + Tolerations allow the scheduler to schedule nodes with matching taints. + More Info: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/ + items: + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . + properties: + effect: + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + type: object + type: object + served: true + storage: true +{{- end }} diff --git a/kubernetes-vault/consul/templates/crd-gatewayclassconfigs.yaml b/kubernetes-vault/consul/templates/crd-gatewayclassconfigs.yaml new file mode 100644 index 0000000..50944ac --- /dev/null +++ b/kubernetes-vault/consul/templates/crd-gatewayclassconfigs.yaml @@ -0,0 +1,1729 @@ +{{- if .Values.connectInject.enabled }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: crd + name: gatewayclassconfigs.mesh.consul.hashicorp.com +spec: + group: mesh.consul.hashicorp.com + names: + kind: GatewayClassConfig + listKind: GatewayClassConfigList + plural: gatewayclassconfigs + singular: gatewayclassconfig + scope: Cluster + versions: + - additionalPrinterColumns: + - description: The age of the resource + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v2beta1 + schema: + openAPIV3Schema: + description: GatewayClassConfig is the Schema for the Mesh Gateway 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: GatewayClassConfigSpec specifies the desired state of the + GatewayClassConfig CRD. + properties: + annotations: + description: Annotations are applied to the created resource + properties: + inheritFromGateway: + description: |- + InheritFromGateway lists the names/keys of annotations or labels to copy from the Gateway resource. + Any name/key included here will override those in Set if specified on the Gateway. + items: + type: string + type: array + set: + additionalProperties: + type: string + description: |- + Set lists the names/keys and values of annotations or labels to set on the resource. + Any name/key included here will be overridden if present in InheritFromGateway and set on the Gateway. + type: object + type: object + deployment: + description: Deployment contains config specific to the Deployment + created from this GatewayClass + properties: + affinity: + description: Affinity specifies the affinity to use on the created + Deployment. + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for + the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. + items: + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated with + the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching the + corresponding nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. + co-locate this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules + (e.g. avoid putting this pod in the same node, zone, etc. + as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + annotations: + description: Annotations are applied to the created resource + properties: + inheritFromGateway: + description: |- + InheritFromGateway lists the names/keys of annotations or labels to copy from the Gateway resource. + Any name/key included here will override those in Set if specified on the Gateway. + items: + type: string + type: array + set: + additionalProperties: + type: string + description: |- + Set lists the names/keys and values of annotations or labels to set on the resource. + Any name/key included here will be overridden if present in InheritFromGateway and set on the Gateway. + type: object + type: object + container: + description: Container contains config specific to the created + Deployment's container. + properties: + consul: + description: Consul specifies configuration for the consul-dataplane + container + properties: + logging: + description: Logging specifies the logging configuration + for Consul Dataplane + properties: + level: + description: Level sets the logging level for Consul + Dataplane (debug, info, etc.) + type: string + type: object + type: object + hostPort: + description: HostPort specifies a port to be exposed to the + external host network + format: int32 + type: integer + portModifier: + description: |- + PortModifier specifies the value to be added to every port value for listeners on this gateway. + This is generally used to avoid binding to privileged ports in the container. + format: int32 + type: integer + resources: + description: Resources specifies the resource requirements + for the created Deployment's container + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + type: object + dnsPolicy: + description: DNSPolicy specifies the dns policy to use. These + are set on a per pod basis. + enum: + - Default + - ClusterFirst + - ClusterFirstWithHostNet + - None + type: string + hostNetwork: + description: HostNetwork specifies whether the gateway pods should + run on the host network. + type: boolean + initContainer: + description: InitContainer contains config specific to the created + Deployment's init container. + properties: + consul: + description: Consul specifies configuration for the consul-k8s-control-plane + init container + properties: + logging: + description: Logging specifies the logging configuration + for Consul Dataplane + properties: + level: + description: Level sets the logging level for Consul + Dataplane (debug, info, etc.) + type: string + type: object + type: object + resources: + description: Resources specifies the resource requirements + for the created Deployment's init container + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + type: object + labels: + description: Labels are applied to the created resource + properties: + inheritFromGateway: + description: |- + InheritFromGateway lists the names/keys of annotations or labels to copy from the Gateway resource. + Any name/key included here will override those in Set if specified on the Gateway. + items: + type: string + type: array + set: + additionalProperties: + type: string + description: |- + Set lists the names/keys and values of annotations or labels to set on the resource. + Any name/key included here will be overridden if present in InheritFromGateway and set on the Gateway. + type: object + type: object + nodeSelector: + additionalProperties: + type: string + description: |- + NodeSelector is a feature that constrains the scheduling of a pod to nodes that + match specified labels. + By defining NodeSelector in a pod's configuration, you can ensure that the pod is + only scheduled to nodes with the corresponding labels, providing a way to + influence the placement of workloads based on node attributes. + More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + type: object + priorityClassName: + description: PriorityClassName specifies the priority class name + to use on the created Deployment. + type: string + replicas: + description: Replicas specifies the configuration to control the + number of replicas for the created Deployment. + properties: + default: + description: Default is the number of replicas assigned to + the Deployment when created + format: int32 + type: integer + max: + description: |- + Max is the maximum number of replicas allowed for a gateway with this class. + If the replica count exceeds this value due to manual or automated scaling, + the replica count will be restored to this value. + format: int32 + type: integer + min: + description: |- + Min is the minimum number of replicas allowed for a gateway with this class. + If the replica count drops below this value due to manual or automated scaling, + the replica count will be restored to this value. + format: int32 + type: integer + type: object + securityContext: + description: SecurityContext specifies the security context for + the created Deployment's Pod. + properties: + fsGroup: + description: |- + A special supplemental group that applies to all containers in a pod. + Some volume types allow the Kubelet to change the ownership of that volume + to be owned by the pod: + + + 1. The owning GID will be the FSGroup + 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) + 3. The permission bits are OR'd with rw-rw---- + + + If unset, the Kubelet will not modify the ownership and permissions of any volume. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + fsGroupChangePolicy: + description: |- + fsGroupChangePolicy defines behavior of changing ownership and permission of the volume + before being exposed inside Pod. This field will only apply to + volume types which support fsGroup based ownership(and permissions). + It will have no effect on ephemeral volume types such as: secret, configmaps + and emptydir. + Valid values are "OnRootMismatch" and "Always". If not specified, "Always" is used. + Note that this field cannot be set when spec.os.name is windows. + type: string + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to all containers. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in SecurityContext. If set in + both SecurityContext and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + supplementalGroups: + description: |- + A list of groups applied to the first process run in each container, in addition + to the container's primary GID, the fsGroup (if specified), and group memberships + defined in the container image for the uid of the container process. If unspecified, + no additional groups are added to any container. Note that group memberships + defined in the container image for the uid of the container process are still effective, + even if they are not included in this list. + Note that this field cannot be set when spec.os.name is windows. + items: + format: int64 + type: integer + type: array + sysctls: + description: |- + Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported + sysctls (by the container runtime) might fail to launch. + Note that this field cannot be set when spec.os.name is windows. + items: + description: Sysctl defines a kernel parameter to be set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options within a container's SecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + tolerations: + description: Tolerations specifies the tolerations to use on the + created Deployment. + items: + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . + properties: + effect: + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + topologySpreadConstraints: + description: |- + TopologySpreadConstraints is a feature that controls how pods are spead across your topology. + More info: https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ + items: + description: TopologySpreadConstraint specifies how to spread + matching pods among the given topology. + properties: + labelSelector: + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods + in their corresponding topology domain. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + + + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. + format: int32 + type: integer + minDomains: + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + + + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + + + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). + format: int32 + type: integer + nodeAffinityPolicy: + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + + + If this value is nil, the behavior is equivalent to the Honor policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + nodeTaintsPolicy: + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating + pod topology spread skew. Options are: + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + + + If this value is nil, the behavior is equivalent to the Ignore policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + topologyKey: + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. + It's a required field. + type: string + whenUnsatisfiable: + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + type: object + labels: + description: Labels are applied to the created resource + properties: + inheritFromGateway: + description: |- + InheritFromGateway lists the names/keys of annotations or labels to copy from the Gateway resource. + Any name/key included here will override those in Set if specified on the Gateway. + items: + type: string + type: array + set: + additionalProperties: + type: string + description: |- + Set lists the names/keys and values of annotations or labels to set on the resource. + Any name/key included here will be overridden if present in InheritFromGateway and set on the Gateway. + type: object + type: object + role: + description: Role contains config specific to the Role created from + this GatewayClass + properties: + annotations: + description: Annotations are applied to the created resource + properties: + inheritFromGateway: + description: |- + InheritFromGateway lists the names/keys of annotations or labels to copy from the Gateway resource. + Any name/key included here will override those in Set if specified on the Gateway. + items: + type: string + type: array + set: + additionalProperties: + type: string + description: |- + Set lists the names/keys and values of annotations or labels to set on the resource. + Any name/key included here will be overridden if present in InheritFromGateway and set on the Gateway. + type: object + type: object + labels: + description: Labels are applied to the created resource + properties: + inheritFromGateway: + description: |- + InheritFromGateway lists the names/keys of annotations or labels to copy from the Gateway resource. + Any name/key included here will override those in Set if specified on the Gateway. + items: + type: string + type: array + set: + additionalProperties: + type: string + description: |- + Set lists the names/keys and values of annotations or labels to set on the resource. + Any name/key included here will be overridden if present in InheritFromGateway and set on the Gateway. + type: object + type: object + type: object + roleBinding: + description: RoleBinding contains config specific to the RoleBinding + created from this GatewayClass + properties: + annotations: + description: Annotations are applied to the created resource + properties: + inheritFromGateway: + description: |- + InheritFromGateway lists the names/keys of annotations or labels to copy from the Gateway resource. + Any name/key included here will override those in Set if specified on the Gateway. + items: + type: string + type: array + set: + additionalProperties: + type: string + description: |- + Set lists the names/keys and values of annotations or labels to set on the resource. + Any name/key included here will be overridden if present in InheritFromGateway and set on the Gateway. + type: object + type: object + labels: + description: Labels are applied to the created resource + properties: + inheritFromGateway: + description: |- + InheritFromGateway lists the names/keys of annotations or labels to copy from the Gateway resource. + Any name/key included here will override those in Set if specified on the Gateway. + items: + type: string + type: array + set: + additionalProperties: + type: string + description: |- + Set lists the names/keys and values of annotations or labels to set on the resource. + Any name/key included here will be overridden if present in InheritFromGateway and set on the Gateway. + type: object + type: object + type: object + service: + description: Service contains config specific to the Service created + from this GatewayClass + properties: + annotations: + description: Annotations are applied to the created resource + properties: + inheritFromGateway: + description: |- + InheritFromGateway lists the names/keys of annotations or labels to copy from the Gateway resource. + Any name/key included here will override those in Set if specified on the Gateway. + items: + type: string + type: array + set: + additionalProperties: + type: string + description: |- + Set lists the names/keys and values of annotations or labels to set on the resource. + Any name/key included here will be overridden if present in InheritFromGateway and set on the Gateway. + type: object + type: object + labels: + description: Labels are applied to the created resource + properties: + inheritFromGateway: + description: |- + InheritFromGateway lists the names/keys of annotations or labels to copy from the Gateway resource. + Any name/key included here will override those in Set if specified on the Gateway. + items: + type: string + type: array + set: + additionalProperties: + type: string + description: |- + Set lists the names/keys and values of annotations or labels to set on the resource. + Any name/key included here will be overridden if present in InheritFromGateway and set on the Gateway. + type: object + type: object + type: + description: Type specifies the type of Service to use (LoadBalancer, + ClusterIP, etc.) + enum: + - ClusterIP + - NodePort + - LoadBalancer + type: string + type: object + serviceAccount: + description: ServiceAccount contains config specific to the corev1.ServiceAccount + created from this GatewayClass + properties: + annotations: + description: Annotations are applied to the created resource + properties: + inheritFromGateway: + description: |- + InheritFromGateway lists the names/keys of annotations or labels to copy from the Gateway resource. + Any name/key included here will override those in Set if specified on the Gateway. + items: + type: string + type: array + set: + additionalProperties: + type: string + description: |- + Set lists the names/keys and values of annotations or labels to set on the resource. + Any name/key included here will be overridden if present in InheritFromGateway and set on the Gateway. + type: object + type: object + labels: + description: Labels are applied to the created resource + properties: + inheritFromGateway: + description: |- + InheritFromGateway lists the names/keys of annotations or labels to copy from the Gateway resource. + Any name/key included here will override those in Set if specified on the Gateway. + items: + type: string + type: array + set: + additionalProperties: + type: string + description: |- + Set lists the names/keys and values of annotations or labels to set on the resource. + Any name/key included here will be overridden if present in InheritFromGateway and set on the Gateway. + type: object + type: object + type: object + type: object + status: + properties: + conditions: + description: Conditions indicate the latest available observations + of a resource's current state. + items: + description: |- + Conditions define a readiness condition for a Consul resource. + See: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties + properties: + lastTransitionTime: + description: LastTransitionTime is the 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 condition. + type: string + required: + - status + - type + type: object + type: array + lastSyncedTime: + description: LastSyncedTime is the last time the resource successfully + synced with Consul. + format: date-time + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- end }} diff --git a/kubernetes-vault/consul/templates/crd-gatewayclasses-external.yaml b/kubernetes-vault/consul/templates/crd-gatewayclasses-external.yaml new file mode 100644 index 0000000..93435b7 --- /dev/null +++ b/kubernetes-vault/consul/templates/crd-gatewayclasses-external.yaml @@ -0,0 +1,328 @@ +{{- if and .Values.connectInject.enabled .Values.connectInject.apiGateway.manageExternalCRDs }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/1538 + gateway.networking.k8s.io/bundle-version: v0.6.2 + gateway.networking.k8s.io/channel: experimental + creationTimestamp: null + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: crd + name: gatewayclasses.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: GatewayClass + listKind: GatewayClassList + plural: gatewayclasses + shortNames: + - gc + singular: gatewayclass + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .spec.controllerName + name: Controller + type: string + - jsonPath: .status.conditions[?(@.type=="Accepted")].status + name: Accepted + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .spec.description + name: Description + priority: 1 + type: string + deprecated: true + deprecationWarning: The v1alpha2 version of GatewayClass has been deprecated and will be removed in a future release of the API. Please upgrade to v1beta1. + name: v1alpha2 + schema: + openAPIV3Schema: + description: "GatewayClass describes a class of Gateways available to the user for creating Gateway resources. \n It is recommended that this resource be used as a template for Gateways. This means that a Gateway is based on the state of the GatewayClass at the time it was created and changes to the GatewayClass or associated parameters are not propagated down to existing Gateways. This recommendation is intended to limit the blast radius of changes to GatewayClass or associated parameters. If implementations choose to propagate GatewayClass changes to existing Gateways, that MUST be clearly documented by the implementation. \n Whenever one or more Gateways are using a GatewayClass, implementations MUST add the `gateway-exists-finalizer.gateway.networking.k8s.io` finalizer on the associated GatewayClass. This ensures that a GatewayClass associated with a Gateway is not deleted while in use. \n GatewayClass is a Cluster level resource." + 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 GatewayClass. + properties: + controllerName: + description: "ControllerName is the name of the controller that is managing Gateways of this class. The value of this field MUST be a domain prefixed path. \n Example: \"example.net/gateway-controller\". \n This field is not mutable and cannot be empty. \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])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + description: + description: Description helps describe a GatewayClass with more details. + maxLength: 64 + type: string + parametersRef: + description: "ParametersRef is a reference to a resource that contains the configuration parameters corresponding to the GatewayClass. This is optional if the controller does not require any additional configuration. \n ParametersRef can reference a standard Kubernetes resource, i.e. ConfigMap, or an implementation-specific custom resource. The resource can be cluster-scoped or namespace-scoped. \n If the referent cannot be found, the GatewayClass's \"InvalidParameters\" status condition will be true. \n Support: Implementation-specific" + properties: + group: + description: Group is the group of the referent. + 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. + 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. This field is required when referring to a Namespace-scoped resource and MUST be unset when referring to a Cluster-scoped resource. + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - group + - kind + - name + type: object + required: + - controllerName + type: object + status: + default: + conditions: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Waiting + status: Unknown + type: Accepted + description: Status defines the current state of GatewayClass. + properties: + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Accepted + description: "Conditions is the current status from the controller for this GatewayClass. \n Controllers should prefer to publish conditions using values of GatewayClassConditionType for the type of each Condition." + 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 \ttype FooStatus struct{ \t // Represents the observations of a foo's current state. \t // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" \t // +patchMergeKey=type \t // +patchStrategy=merge \t // +listType=map \t // +listMapKey=type \t Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n \t // other fields \t}" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .spec.controllerName + name: Controller + type: string + - jsonPath: .status.conditions[?(@.type=="Accepted")].status + name: Accepted + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .spec.description + name: Description + priority: 1 + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: "GatewayClass describes a class of Gateways available to the user for creating Gateway resources. \n It is recommended that this resource be used as a template for Gateways. This means that a Gateway is based on the state of the GatewayClass at the time it was created and changes to the GatewayClass or associated parameters are not propagated down to existing Gateways. This recommendation is intended to limit the blast radius of changes to GatewayClass or associated parameters. If implementations choose to propagate GatewayClass changes to existing Gateways, that MUST be clearly documented by the implementation. \n Whenever one or more Gateways are using a GatewayClass, implementations MUST add the `gateway-exists-finalizer.gateway.networking.k8s.io` finalizer on the associated GatewayClass. This ensures that a GatewayClass associated with a Gateway is not deleted while in use. \n GatewayClass is a Cluster level resource." + 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 GatewayClass. + properties: + controllerName: + description: "ControllerName is the name of the controller that is managing Gateways of this class. The value of this field MUST be a domain prefixed path. \n Example: \"example.net/gateway-controller\". \n This field is not mutable and cannot be empty. \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])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + description: + description: Description helps describe a GatewayClass with more details. + maxLength: 64 + type: string + parametersRef: + description: "ParametersRef is a reference to a resource that contains the configuration parameters corresponding to the GatewayClass. This is optional if the controller does not require any additional configuration. \n ParametersRef can reference a standard Kubernetes resource, i.e. ConfigMap, or an implementation-specific custom resource. The resource can be cluster-scoped or namespace-scoped. \n If the referent cannot be found, the GatewayClass's \"InvalidParameters\" status condition will be true. \n Support: Implementation-specific" + properties: + group: + description: Group is the group of the referent. + 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. + 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. This field is required when referring to a Namespace-scoped resource and MUST be unset when referring to a Cluster-scoped resource. + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - group + - kind + - name + type: object + required: + - controllerName + type: object + status: + default: + conditions: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Waiting + status: Unknown + type: Accepted + description: Status defines the current state of GatewayClass. + properties: + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Accepted + description: "Conditions is the current status from the controller for this GatewayClass. \n Controllers should prefer to publish conditions using values of GatewayClassConditionType for the type of each Condition." + 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 \ttype FooStatus struct{ \t // Represents the observations of a foo's current state. \t // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" \t // +patchMergeKey=type \t // +patchStrategy=merge \t // +listType=map \t // +listMapKey=type \t Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n \t // other fields \t}" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +{{- end }} diff --git a/kubernetes-vault/consul/templates/crd-gatewayclasses.yaml b/kubernetes-vault/consul/templates/crd-gatewayclasses.yaml new file mode 100644 index 0000000..9880d7d --- /dev/null +++ b/kubernetes-vault/consul/templates/crd-gatewayclasses.yaml @@ -0,0 +1,130 @@ +{{- if .Values.connectInject.enabled }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: crd + name: gatewayclasses.mesh.consul.hashicorp.com +spec: + group: mesh.consul.hashicorp.com + names: + kind: GatewayClass + listKind: GatewayClassList + plural: gatewayclasses + singular: gatewayclass + scope: Cluster + versions: + - additionalPrinterColumns: + - description: The age of the resource + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v2beta1 + schema: + openAPIV3Schema: + description: GatewayClass is the Schema for the Gateway Class API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + properties: + controllerName: + description: |- + ControllerName is the name of the Kubernetes controller + that manages Gateways of this class + type: string + description: + description: Description of GatewayClass + type: string + parametersRef: + description: |- + ParametersRef refers to a resource responsible for configuring + the behavior of the GatewayClass. + properties: + group: + description: The Kubernetes Group that the referred object belongs + to + type: string + kind: + description: The Kubernetes Kind that the referred object is + type: string + name: + description: The Name of the referred object + type: string + namespace: + description: The kubernetes namespace that the referred object + is in + type: string + required: + - name + type: object + required: + - controllerName + - parametersRef + type: object + status: + properties: + conditions: + description: Conditions indicate the latest available observations + of a resource's current state. + items: + description: |- + Conditions define a readiness condition for a Consul resource. + See: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties + properties: + lastTransitionTime: + description: LastTransitionTime is the 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 condition. + type: string + required: + - status + - type + type: object + type: array + lastSyncedTime: + description: LastSyncedTime is the last time the resource successfully + synced with Consul. + format: date-time + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- end }} diff --git a/kubernetes-vault/consul/templates/crd-gatewaypolicies.yaml b/kubernetes-vault/consul/templates/crd-gatewaypolicies.yaml new file mode 100644 index 0000000..904b65d --- /dev/null +++ b/kubernetes-vault/consul/templates/crd-gatewaypolicies.yaml @@ -0,0 +1,302 @@ +{{- if .Values.connectInject.enabled }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: crd + name: gatewaypolicies.consul.hashicorp.com +spec: + group: consul.hashicorp.com + names: + kind: GatewayPolicy + listKind: GatewayPolicyList + plural: gatewaypolicies + singular: gatewaypolicy + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The sync status of the resource with Consul + jsonPath: .status.conditions[?(@.type=="Synced")].status + name: Synced + type: string + - description: The last successful synced time of the resource with Consul + jsonPath: .status.lastSyncedTime + name: Last Synced + type: date + - description: The age of the resource + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: GatewayPolicy is the Schema for the gatewaypolicies 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: GatewayPolicySpec defines the desired state of GatewayPolicy. + properties: + default: + properties: + jwt: + description: GatewayJWTRequirement holds the list of JWT providers + to be verified against. + properties: + providers: + description: Providers is a list of providers to consider + when verifying a JWT. + items: + description: GatewayJWTProvider holds the provider and claim + verification information. + properties: + name: + description: |- + Name is the name of the JWT provider. There MUST be a corresponding + "jwt-provider" config entry with this name. + type: string + verifyClaims: + description: VerifyClaims is a list of additional claims + to verify in a JWT's payload. + items: + description: GatewayJWTClaimVerification holds the + actual claim information to be verified. + properties: + path: + description: Path is the path to the claim in + the token JSON. + items: + type: string + type: array + value: + description: |- + Value is the expected value at the given path: + - If the type at the path is a list then we verify + that this value is contained in the list. + + + - If the type at the path is a string then we verify + that this value matches. + type: string + required: + - path + - value + type: object + type: array + required: + - name + type: object + type: array + required: + - providers + type: object + type: object + override: + properties: + jwt: + description: GatewayJWTRequirement holds the list of JWT providers + to be verified against. + properties: + providers: + description: Providers is a list of providers to consider + when verifying a JWT. + items: + description: GatewayJWTProvider holds the provider and claim + verification information. + properties: + name: + description: |- + Name is the name of the JWT provider. There MUST be a corresponding + "jwt-provider" config entry with this name. + type: string + verifyClaims: + description: VerifyClaims is a list of additional claims + to verify in a JWT's payload. + items: + description: GatewayJWTClaimVerification holds the + actual claim information to be verified. + properties: + path: + description: Path is the path to the claim in + the token JSON. + items: + type: string + type: array + value: + description: |- + Value is the expected value at the given path: + - If the type at the path is a list then we verify + that this value is contained in the list. + + + - If the type at the path is a string then we verify + that this value matches. + type: string + required: + - path + - value + type: object + type: array + required: + - name + type: object + type: array + required: + - providers + type: object + type: object + targetRef: + description: TargetRef identifies an API object to apply policy to. + properties: + group: + description: Group is the group of the target resource. + maxLength: 253 + minLength: 1 + type: string + kind: + description: Kind is kind of the target resource. + maxLength: 253 + minLength: 1 + type: string + name: + description: Name is the name of the target resource. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referent. When unspecified, the local + namespace is inferred. Even when policy targets a resource in a different + namespace, it may only apply to traffic originating from the same + namespace as the policy. + maxLength: 253 + minLength: 1 + type: string + sectionName: + description: SectionName refers to the listener targeted by this + policy. + 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: + - group + - kind + - name + type: object + required: + - targetRef + type: object + status: + description: GatewayPolicyStatus defines the observed state of the gateway. + properties: + conditions: + description: |- + Conditions describe the current conditions of the Policy. + + + Known condition types are: + + + * "Accepted" + * "ResolvedRefs" + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + 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: {} +{{- end }} diff --git a/kubernetes-vault/consul/templates/crd-gateways-external.yaml b/kubernetes-vault/consul/templates/crd-gateways-external.yaml new file mode 100644 index 0000000..41df349 --- /dev/null +++ b/kubernetes-vault/consul/templates/crd-gateways-external.yaml @@ -0,0 +1,882 @@ +{{- if and .Values.connectInject.enabled .Values.connectInject.apiGateway.manageExternalCRDs }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/1538 + gateway.networking.k8s.io/bundle-version: v0.6.2 + gateway.networking.k8s.io/channel: experimental + creationTimestamp: null + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: crd + name: gateways.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: Gateway + listKind: GatewayList + plural: gateways + shortNames: + - gtw + singular: gateway + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.gatewayClassName + name: Class + type: string + - jsonPath: .status.addresses[*].value + name: Address + type: string + - jsonPath: .status.conditions[?(@.type=="Programmed")].status + name: Programmed + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + deprecated: true + deprecationWarning: The v1alpha2 version of Gateway has been deprecated and will be removed in a future release of the API. Please upgrade to v1beta1. + name: v1alpha2 + schema: + openAPIV3Schema: + description: Gateway represents an instance of a service-traffic handling infrastructure by binding Listeners to a set of IP addresses. + 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 Gateway. + properties: + addresses: + description: "Addresses requested for this Gateway. This is optional and behavior can depend on the implementation. If a value is set in the spec and the requested address is invalid or unavailable, the implementation MUST indicate this in the associated entry in GatewayStatus.Addresses. \n The Addresses field represents a request for the address(es) on the \"outside of the Gateway\", that traffic bound for this Gateway will use. This could be the IP address or hostname of an external load balancer or other networking infrastructure, or some other address that traffic will be sent to. \n The .listener.hostname field is used to route traffic that has already arrived at the Gateway to the correct in-cluster destination. \n If no Addresses are specified, the implementation MAY schedule the Gateway in an implementation-specific manner, assigning an appropriate set of Addresses. \n The implementation MUST bind all Listeners to every GatewayAddress that it assigns to the Gateway and add a corresponding entry in GatewayStatus.Addresses. \n Support: Extended" + items: + description: GatewayAddress describes an address that can be bound to a Gateway. + properties: + type: + default: IPAddress + description: Type of the address. + maxLength: 253 + minLength: 1 + pattern: ^Hostname|IPAddress|NamedAddress|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + value: + description: "Value of the address. The validity of the values will depend on the type and support by the controller. \n Examples: `1.2.3.4`, `128::1`, `my-ip-address`." + maxLength: 253 + minLength: 1 + type: string + required: + - value + type: object + maxItems: 16 + type: array + gatewayClassName: + description: GatewayClassName used for this Gateway. This is the name of a GatewayClass resource. + maxLength: 253 + minLength: 1 + type: string + listeners: + description: "Listeners associated with this Gateway. Listeners define logical endpoints that are bound on this Gateway's addresses. At least one Listener MUST be specified. \n Each listener in a Gateway must have a unique combination of Hostname, Port, and Protocol. \n An implementation MAY group Listeners by Port and then collapse each group of Listeners into a single Listener if the implementation determines that the Listeners in the group are \"compatible\". An implementation MAY also group together and collapse compatible Listeners belonging to different Gateways. \n For example, an implementation might consider Listeners to be compatible with each other if all of the following conditions are met: \n 1. Either each Listener within the group specifies the \"HTTP\" Protocol or each Listener within the group specifies either the \"HTTPS\" or \"TLS\" Protocol. \n 2. Each Listener within the group specifies a Hostname that is unique within the group. \n 3. As a special case, one Listener within a group may omit Hostname, in which case this Listener matches when no other Listener matches. \n If the implementation does collapse compatible Listeners, the hostname provided in the incoming client request MUST be matched to a Listener to find the correct set of Routes. The incoming hostname MUST be matched using the Hostname field for each Listener in order of most to least specific. That is, exact matches must be processed before wildcard matches. \n If this field specifies multiple Listeners that have the same Port value but are not compatible, the implementation must raise a \"Conflicted\" condition in the Listener status. \n Support: Core" + items: + description: Listener embodies the concept of a logical endpoint where a Gateway accepts network connections. + properties: + allowedRoutes: + default: + namespaces: + from: Same + description: "AllowedRoutes defines the types of routes that MAY be attached to a Listener and the trusted namespaces where those Route resources MAY be present. \n Although a client request may match multiple route rules, only one rule may ultimately receive the request. Matching precedence MUST be determined in order of the following criteria: \n * The most specific match as defined by the Route type. * The oldest Route based on creation timestamp. For example, a Route with a creation timestamp of \"2020-09-08 01:02:03\" is given precedence over a Route with a creation timestamp of \"2020-09-08 01:02:04\". * If everything else is equivalent, the Route appearing first in alphabetical order (namespace/name) should be given precedence. For example, foo/bar is given precedence over foo/baz. \n All valid rules within a Route attached to this Listener should be implemented. Invalid Route rules can be ignored (sometimes that will mean the full Route). If a Route rule transitions from valid to invalid, support for that Route rule should be dropped to ensure consistency. For example, even if a filter specified by a Route rule is invalid, the rest of the rules within that Route should still be supported. \n Support: Core" + properties: + kinds: + description: "Kinds specifies the groups and kinds of Routes that are allowed to bind to this Gateway Listener. When unspecified or empty, the kinds of Routes selected are determined using the Listener protocol. \n A RouteGroupKind MUST correspond to kinds of Routes that are compatible with the application protocol specified in the Listener's Protocol field. If an implementation does not support or recognize this resource type, it MUST set the \"ResolvedRefs\" condition to False for this Listener with the \"InvalidRouteKinds\" reason. \n Support: Core" + items: + description: RouteGroupKind indicates the group and kind of a Route resource. + properties: + group: + default: gateway.networking.k8s.io + description: Group is the group of the Route. + 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 Route. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + required: + - kind + type: object + maxItems: 8 + type: array + namespaces: + default: + from: Same + description: "Namespaces indicates namespaces from which Routes may be attached to this Listener. This is restricted to the namespace of this Gateway by default. \n Support: Core" + properties: + from: + default: Same + description: "From indicates where Routes will be selected for this Gateway. Possible values are: * All: Routes in all namespaces may be used by this Gateway. * Selector: Routes in namespaces selected by the selector may be used by this Gateway. * Same: Only Routes in the same namespace may be used by this Gateway. \n Support: Core" + enum: + - All + - Selector + - Same + type: string + selector: + description: "Selector must be specified when From is set to \"Selector\". In that case, only Routes in Namespaces matching this Selector will be selected by this Gateway. This field is ignored for other values of \"From\". \n Support: Core" + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + type: object + type: object + hostname: + description: "Hostname specifies the virtual hostname to match for protocol types that define this concept. When unspecified, all hostnames are matched. This field is ignored for protocols that don't require hostname based matching. \n Implementations MUST apply Hostname matching appropriately for each of the following protocols: \n * TLS: The Listener Hostname MUST match the SNI. * HTTP: The Listener Hostname MUST match the Host header of the request. * HTTPS: The Listener Hostname SHOULD match at both the TLS and HTTP protocol layers as described above. If an implementation does not ensure that both the SNI and Host header match the Listener hostname, it MUST clearly document that. \n For HTTPRoute and TLSRoute resources, there is an interaction with the `spec.hostnames` array. When both listener and route specify hostnames, there MUST be an intersection between the values for a Route to be accepted. For more information, refer to the Route specific Hostnames documentation. \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 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 + name: + description: "Name is the name of the Listener. This name MUST be unique within a 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 + port: + description: "Port is the network port. Multiple listeners may use the same port, subject to the Listener compatibility rules. \n Support: Core" + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + description: "Protocol specifies the network protocol this listener expects to receive. \n Support: Core" + maxLength: 255 + minLength: 1 + pattern: ^[a-zA-Z0-9]([-a-zSA-Z0-9]*[a-zA-Z0-9])?$|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9]+$ + type: string + tls: + description: "TLS is the TLS configuration for the Listener. This field is required if the Protocol field is \"HTTPS\" or \"TLS\". It is invalid to set this field if the Protocol field is \"HTTP\", \"TCP\", or \"UDP\". \n The association of SNIs to Certificate defined in GatewayTLSConfig is defined based on the Hostname field for this listener. \n The GatewayClass MUST use the longest matching SNI out of all available certificates for any TLS handshake. \n Support: Core" + properties: + certificateRefs: + description: "CertificateRefs contains a series of references to Kubernetes objects that contains TLS certificates and private keys. These certificates are used to establish a TLS handshake for requests that match the hostname of the associated listener. \n A single CertificateRef to a Kubernetes Secret has \"Core\" support. Implementations MAY choose to support attaching multiple certificates to a Listener, but this behavior is implementation-specific. \n References to a resource in different namespace are invalid UNLESS there is a ReferenceGrant in the target namespace that allows the certificate to be attached. If a ReferenceGrant does not allow this reference, the \"ResolvedRefs\" condition MUST be set to False for this listener with the \"RefNotPermitted\" reason. \n This field is required to have at least one element when the mode is set to \"Terminate\" (default) and is optional otherwise. \n CertificateRefs can reference to standard Kubernetes resources, i.e. Secret, or implementation-specific custom resources. \n Support: Core - A single reference to a Kubernetes Secret of type kubernetes.io/tls \n Support: Implementation-specific (More than one reference or other resource types)" + items: + description: "SecretObjectReference identifies an API object including its namespace, defaulting to Secret. \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. \n References to objects with invalid Group and Kind are not valid, and must be rejected by the implementation, with appropriate Conditions set on the containing object." + 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: Secret + 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 + 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 + required: + - name + type: object + maxItems: 64 + type: array + mode: + default: Terminate + description: "Mode defines the TLS behavior for the TLS session initiated by the client. There are two possible modes: \n - Terminate: The TLS session between the downstream client and the Gateway is terminated at the Gateway. This mode requires certificateRefs to be set and contain at least one element. - Passthrough: The TLS session is NOT terminated by the Gateway. This implies that the Gateway can't decipher the TLS stream except for the ClientHello message of the TLS protocol. CertificateRefs field is ignored in this mode. \n Support: Core" + enum: + - Terminate + - Passthrough + type: string + options: + additionalProperties: + description: AnnotationValue is the value of an annotation in Gateway API. This is used for validation of maps such as TLS options. This roughly matches Kubernetes annotation validation, although the length validation in that case is based on the entire size of the annotations struct. + maxLength: 4096 + minLength: 0 + type: string + description: "Options are a list of key/value pairs to enable extended TLS configuration for each implementation. For example, configuring the minimum TLS version or supported cipher suites. \n A set of common keys MAY be defined by the API in the future. To avoid any ambiguity, implementation-specific definitions MUST use domain-prefixed names, such as `example.com/my-custom-option`. Un-prefixed names are reserved for key names defined by Gateway API. \n Support: Implementation-specific" + maxProperties: 16 + type: object + type: object + required: + - name + - port + - protocol + type: object + maxItems: 64 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + required: + - gatewayClassName + - listeners + type: object + status: + default: + conditions: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: NotReconciled + status: Unknown + type: Accepted + description: Status defines the current state of Gateway. + properties: + addresses: + description: Addresses lists the IP addresses that have actually been bound to the Gateway. These addresses may differ from the addresses in the Spec, e.g. if the Gateway automatically assigns an address from a reserved pool. + items: + description: GatewayAddress describes an address that can be bound to a Gateway. + properties: + type: + default: IPAddress + description: Type of the address. + maxLength: 253 + minLength: 1 + pattern: ^Hostname|IPAddress|NamedAddress|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + value: + description: "Value of the address. The validity of the values will depend on the type and support by the controller. \n Examples: `1.2.3.4`, `128::1`, `my-ip-address`." + maxLength: 253 + minLength: 1 + type: string + required: + - value + type: object + maxItems: 16 + type: array + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Accepted + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Programmed + description: "Conditions describe the current conditions of the Gateway. \n Implementations should prefer to express Gateway conditions using the `GatewayConditionType` and `GatewayConditionReason` constants so that operators and tools can converge on a common vocabulary to describe Gateway state. \n Known condition types are: \n * \"Accepted\" * \"Ready\"" + 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 \ttype FooStatus struct{ \t // Represents the observations of a foo's current state. \t // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" \t // +patchMergeKey=type \t // +patchStrategy=merge \t // +listType=map \t // +listMapKey=type \t Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n \t // other fields \t}" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + listeners: + description: Listeners provide status for each unique listener port defined in the Spec. + items: + description: ListenerStatus is the status associated with a Listener. + properties: + attachedRoutes: + description: AttachedRoutes represents the total number of Routes that have been successfully attached to this Listener. + format: int32 + type: integer + conditions: + description: Conditions describe the current condition of this listener. + 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 \ttype FooStatus struct{ \t // Represents the observations of a foo's current state. \t // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" \t // +patchMergeKey=type \t // +patchStrategy=merge \t // +listType=map \t // +listMapKey=type \t Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n \t // other fields \t}" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + name: + description: Name is the name of the Listener that this status corresponds to. + 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 + supportedKinds: + description: "SupportedKinds is the list indicating the Kinds supported by this listener. This MUST represent the kinds an implementation supports for that Listener configuration. \n If kinds are specified in Spec that are not supported, they MUST NOT appear in this list and an implementation MUST set the \"ResolvedRefs\" condition to \"False\" with the \"InvalidRouteKinds\" reason. If both valid and invalid Route kinds are specified, the implementation MUST reference the valid Route kinds that have been specified." + items: + description: RouteGroupKind indicates the group and kind of a Route resource. + properties: + group: + default: gateway.networking.k8s.io + description: Group is the group of the Route. + 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 Route. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + required: + - kind + type: object + maxItems: 8 + type: array + required: + - attachedRoutes + - conditions + - name + - supportedKinds + type: object + maxItems: 64 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .spec.gatewayClassName + name: Class + type: string + - jsonPath: .status.addresses[*].value + name: Address + type: string + - jsonPath: .status.conditions[?(@.type=="Programmed")].status + name: Programmed + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: Gateway represents an instance of a service-traffic handling infrastructure by binding Listeners to a set of IP addresses. + 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 Gateway. + properties: + addresses: + description: "Addresses requested for this Gateway. This is optional and behavior can depend on the implementation. If a value is set in the spec and the requested address is invalid or unavailable, the implementation MUST indicate this in the associated entry in GatewayStatus.Addresses. \n The Addresses field represents a request for the address(es) on the \"outside of the Gateway\", that traffic bound for this Gateway will use. This could be the IP address or hostname of an external load balancer or other networking infrastructure, or some other address that traffic will be sent to. \n The .listener.hostname field is used to route traffic that has already arrived at the Gateway to the correct in-cluster destination. \n If no Addresses are specified, the implementation MAY schedule the Gateway in an implementation-specific manner, assigning an appropriate set of Addresses. \n The implementation MUST bind all Listeners to every GatewayAddress that it assigns to the Gateway and add a corresponding entry in GatewayStatus.Addresses. \n Support: Extended" + items: + description: GatewayAddress describes an address that can be bound to a Gateway. + properties: + type: + default: IPAddress + description: Type of the address. + maxLength: 253 + minLength: 1 + pattern: ^Hostname|IPAddress|NamedAddress|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + value: + description: "Value of the address. The validity of the values will depend on the type and support by the controller. \n Examples: `1.2.3.4`, `128::1`, `my-ip-address`." + maxLength: 253 + minLength: 1 + type: string + required: + - value + type: object + maxItems: 16 + type: array + gatewayClassName: + description: GatewayClassName used for this Gateway. This is the name of a GatewayClass resource. + maxLength: 253 + minLength: 1 + type: string + listeners: + description: "Listeners associated with this Gateway. Listeners define logical endpoints that are bound on this Gateway's addresses. At least one Listener MUST be specified. \n Each listener in a Gateway must have a unique combination of Hostname, Port, and Protocol. \n An implementation MAY group Listeners by Port and then collapse each group of Listeners into a single Listener if the implementation determines that the Listeners in the group are \"compatible\". An implementation MAY also group together and collapse compatible Listeners belonging to different Gateways. \n For example, an implementation might consider Listeners to be compatible with each other if all of the following conditions are met: \n 1. Either each Listener within the group specifies the \"HTTP\" Protocol or each Listener within the group specifies either the \"HTTPS\" or \"TLS\" Protocol. \n 2. Each Listener within the group specifies a Hostname that is unique within the group. \n 3. As a special case, one Listener within a group may omit Hostname, in which case this Listener matches when no other Listener matches. \n If the implementation does collapse compatible Listeners, the hostname provided in the incoming client request MUST be matched to a Listener to find the correct set of Routes. The incoming hostname MUST be matched using the Hostname field for each Listener in order of most to least specific. That is, exact matches must be processed before wildcard matches. \n If this field specifies multiple Listeners that have the same Port value but are not compatible, the implementation must raise a \"Conflicted\" condition in the Listener status. \n Support: Core" + items: + description: Listener embodies the concept of a logical endpoint where a Gateway accepts network connections. + properties: + allowedRoutes: + default: + namespaces: + from: Same + description: "AllowedRoutes defines the types of routes that MAY be attached to a Listener and the trusted namespaces where those Route resources MAY be present. \n Although a client request may match multiple route rules, only one rule may ultimately receive the request. Matching precedence MUST be determined in order of the following criteria: \n * The most specific match as defined by the Route type. * The oldest Route based on creation timestamp. For example, a Route with a creation timestamp of \"2020-09-08 01:02:03\" is given precedence over a Route with a creation timestamp of \"2020-09-08 01:02:04\". * If everything else is equivalent, the Route appearing first in alphabetical order (namespace/name) should be given precedence. For example, foo/bar is given precedence over foo/baz. \n All valid rules within a Route attached to this Listener should be implemented. Invalid Route rules can be ignored (sometimes that will mean the full Route). If a Route rule transitions from valid to invalid, support for that Route rule should be dropped to ensure consistency. For example, even if a filter specified by a Route rule is invalid, the rest of the rules within that Route should still be supported. \n Support: Core" + properties: + kinds: + description: "Kinds specifies the groups and kinds of Routes that are allowed to bind to this Gateway Listener. When unspecified or empty, the kinds of Routes selected are determined using the Listener protocol. \n A RouteGroupKind MUST correspond to kinds of Routes that are compatible with the application protocol specified in the Listener's Protocol field. If an implementation does not support or recognize this resource type, it MUST set the \"ResolvedRefs\" condition to False for this Listener with the \"InvalidRouteKinds\" reason. \n Support: Core" + items: + description: RouteGroupKind indicates the group and kind of a Route resource. + properties: + group: + default: gateway.networking.k8s.io + description: Group is the group of the Route. + 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 Route. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + required: + - kind + type: object + maxItems: 8 + type: array + namespaces: + default: + from: Same + description: "Namespaces indicates namespaces from which Routes may be attached to this Listener. This is restricted to the namespace of this Gateway by default. \n Support: Core" + properties: + from: + default: Same + description: "From indicates where Routes will be selected for this Gateway. Possible values are: * All: Routes in all namespaces may be used by this Gateway. * Selector: Routes in namespaces selected by the selector may be used by this Gateway. * Same: Only Routes in the same namespace may be used by this Gateway. \n Support: Core" + enum: + - All + - Selector + - Same + type: string + selector: + description: "Selector must be specified when From is set to \"Selector\". In that case, only Routes in Namespaces matching this Selector will be selected by this Gateway. This field is ignored for other values of \"From\". \n Support: Core" + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + type: object + type: object + hostname: + description: "Hostname specifies the virtual hostname to match for protocol types that define this concept. When unspecified, all hostnames are matched. This field is ignored for protocols that don't require hostname based matching. \n Implementations MUST apply Hostname matching appropriately for each of the following protocols: \n * TLS: The Listener Hostname MUST match the SNI. * HTTP: The Listener Hostname MUST match the Host header of the request. * HTTPS: The Listener Hostname SHOULD match at both the TLS and HTTP protocol layers as described above. If an implementation does not ensure that both the SNI and Host header match the Listener hostname, it MUST clearly document that. \n For HTTPRoute and TLSRoute resources, there is an interaction with the `spec.hostnames` array. When both listener and route specify hostnames, there MUST be an intersection between the values for a Route to be accepted. For more information, refer to the Route specific Hostnames documentation. \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 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 + name: + description: "Name is the name of the Listener. This name MUST be unique within a 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 + port: + description: "Port is the network port. Multiple listeners may use the same port, subject to the Listener compatibility rules. \n Support: Core" + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + description: "Protocol specifies the network protocol this listener expects to receive. \n Support: Core" + maxLength: 255 + minLength: 1 + pattern: ^[a-zA-Z0-9]([-a-zSA-Z0-9]*[a-zA-Z0-9])?$|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9]+$ + type: string + tls: + description: "TLS is the TLS configuration for the Listener. This field is required if the Protocol field is \"HTTPS\" or \"TLS\". It is invalid to set this field if the Protocol field is \"HTTP\", \"TCP\", or \"UDP\". \n The association of SNIs to Certificate defined in GatewayTLSConfig is defined based on the Hostname field for this listener. \n The GatewayClass MUST use the longest matching SNI out of all available certificates for any TLS handshake. \n Support: Core" + properties: + certificateRefs: + description: "CertificateRefs contains a series of references to Kubernetes objects that contains TLS certificates and private keys. These certificates are used to establish a TLS handshake for requests that match the hostname of the associated listener. \n A single CertificateRef to a Kubernetes Secret has \"Core\" support. Implementations MAY choose to support attaching multiple certificates to a Listener, but this behavior is implementation-specific. \n References to a resource in different namespace are invalid UNLESS there is a ReferenceGrant in the target namespace that allows the certificate to be attached. If a ReferenceGrant does not allow this reference, the \"ResolvedRefs\" condition MUST be set to False for this listener with the \"RefNotPermitted\" reason. \n This field is required to have at least one element when the mode is set to \"Terminate\" (default) and is optional otherwise. \n CertificateRefs can reference to standard Kubernetes resources, i.e. Secret, or implementation-specific custom resources. \n Support: Core - A single reference to a Kubernetes Secret of type kubernetes.io/tls \n Support: Implementation-specific (More than one reference or other resource types)" + items: + description: "SecretObjectReference identifies an API object including its namespace, defaulting to Secret. \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. \n References to objects with invalid Group and Kind are not valid, and must be rejected by the implementation, with appropriate Conditions set on the containing object." + 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: Secret + 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 + 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 + required: + - name + type: object + maxItems: 64 + type: array + mode: + default: Terminate + description: "Mode defines the TLS behavior for the TLS session initiated by the client. There are two possible modes: \n - Terminate: The TLS session between the downstream client and the Gateway is terminated at the Gateway. This mode requires certificateRefs to be set and contain at least one element. - Passthrough: The TLS session is NOT terminated by the Gateway. This implies that the Gateway can't decipher the TLS stream except for the ClientHello message of the TLS protocol. CertificateRefs field is ignored in this mode. \n Support: Core" + enum: + - Terminate + - Passthrough + type: string + options: + additionalProperties: + description: AnnotationValue is the value of an annotation in Gateway API. This is used for validation of maps such as TLS options. This roughly matches Kubernetes annotation validation, although the length validation in that case is based on the entire size of the annotations struct. + maxLength: 4096 + minLength: 0 + type: string + description: "Options are a list of key/value pairs to enable extended TLS configuration for each implementation. For example, configuring the minimum TLS version or supported cipher suites. \n A set of common keys MAY be defined by the API in the future. To avoid any ambiguity, implementation-specific definitions MUST use domain-prefixed names, such as `example.com/my-custom-option`. Un-prefixed names are reserved for key names defined by Gateway API. \n Support: Implementation-specific" + maxProperties: 16 + type: object + type: object + required: + - name + - port + - protocol + type: object + maxItems: 64 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + required: + - gatewayClassName + - listeners + type: object + status: + default: + conditions: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: NotReconciled + status: Unknown + type: Accepted + description: Status defines the current state of Gateway. + properties: + addresses: + description: Addresses lists the IP addresses that have actually been bound to the Gateway. These addresses may differ from the addresses in the Spec, e.g. if the Gateway automatically assigns an address from a reserved pool. + items: + description: GatewayAddress describes an address that can be bound to a Gateway. + properties: + type: + default: IPAddress + description: Type of the address. + maxLength: 253 + minLength: 1 + pattern: ^Hostname|IPAddress|NamedAddress|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + value: + description: "Value of the address. The validity of the values will depend on the type and support by the controller. \n Examples: `1.2.3.4`, `128::1`, `my-ip-address`." + maxLength: 253 + minLength: 1 + type: string + required: + - value + type: object + maxItems: 16 + type: array + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Accepted + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Programmed + description: "Conditions describe the current conditions of the Gateway. \n Implementations should prefer to express Gateway conditions using the `GatewayConditionType` and `GatewayConditionReason` constants so that operators and tools can converge on a common vocabulary to describe Gateway state. \n Known condition types are: \n * \"Accepted\" * \"Ready\"" + 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 \ttype FooStatus struct{ \t // Represents the observations of a foo's current state. \t // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" \t // +patchMergeKey=type \t // +patchStrategy=merge \t // +listType=map \t // +listMapKey=type \t Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n \t // other fields \t}" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + listeners: + description: Listeners provide status for each unique listener port defined in the Spec. + items: + description: ListenerStatus is the status associated with a Listener. + properties: + attachedRoutes: + description: AttachedRoutes represents the total number of Routes that have been successfully attached to this Listener. + format: int32 + type: integer + conditions: + description: Conditions describe the current condition of this listener. + 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 \ttype FooStatus struct{ \t // Represents the observations of a foo's current state. \t // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" \t // +patchMergeKey=type \t // +patchStrategy=merge \t // +listType=map \t // +listMapKey=type \t Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n \t // other fields \t}" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + name: + description: Name is the name of the Listener that this status corresponds to. + 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 + supportedKinds: + description: "SupportedKinds is the list indicating the Kinds supported by this listener. This MUST represent the kinds an implementation supports for that Listener configuration. \n If kinds are specified in Spec that are not supported, they MUST NOT appear in this list and an implementation MUST set the \"ResolvedRefs\" condition to \"False\" with the \"InvalidRouteKinds\" reason. If both valid and invalid Route kinds are specified, the implementation MUST reference the valid Route kinds that have been specified." + items: + description: RouteGroupKind indicates the group and kind of a Route resource. + properties: + group: + default: gateway.networking.k8s.io + description: Group is the group of the Route. + 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 Route. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + required: + - kind + type: object + maxItems: 8 + type: array + required: + - attachedRoutes + - conditions + - name + - supportedKinds + type: object + maxItems: 64 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +{{- end }} diff --git a/kubernetes-vault/consul/templates/crd-grpcroutes-external.yaml b/kubernetes-vault/consul/templates/crd-grpcroutes-external.yaml new file mode 100644 index 0000000..739ed2c --- /dev/null +++ b/kubernetes-vault/consul/templates/crd-grpcroutes-external.yaml @@ -0,0 +1,766 @@ +{{- if and .Values.connectInject.enabled .Values.connectInject.apiGateway.manageExternalCRDs }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/1538 + gateway.networking.k8s.io/bundle-version: v0.6.2 + gateway.networking.k8s.io/channel: experimental + creationTimestamp: null + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: crd + 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 an 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 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 + required: + - name + type: object + required: + - backendRef + type: object + responseHeaderModifier: + description: "ResponseHeaderModifier defines a schema for a filter that modifies response headers. \n Support: Extended \n " + 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 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 + 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 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 + required: + - name + type: object + required: + - backendRef + type: object + responseHeaderModifier: + description: "ResponseHeaderModifier defines a schema for a filter that modifies response headers. \n Support: Extended \n " + 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: + default: + - method: + type: Exact + 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: + default: + type: Exact + 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. \n A GRPC Method must be a valid Protobuf Method (https://protobuf.com/docs/language-spec#methods)." + maxLength: 1024 + pattern: ^[A-Za-z_][A-Za-z_0-9]*$ + 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. \n A GRPC Service must be a valid Protobuf Type Name (https://protobuf.com/docs/language-spec#type-references)." + maxLength: 1024 + pattern: ^(?i)\.?[a-z_][a-z_0-9]*(\.[a-z_][a-z_0-9]*)*$ + 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 \ttype FooStatus struct{ \t // Represents the observations of a foo's current state. \t // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" \t // +patchMergeKey=type \t // +patchStrategy=merge \t // +listType=map \t // +listMapKey=type \t Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n \t // other fields \t}" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + 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: [] + storedVersions: [] +{{- end }} diff --git a/kubernetes-vault/consul/templates/crd-grpcroutes.yaml b/kubernetes-vault/consul/templates/crd-grpcroutes.yaml new file mode 100644 index 0000000..8d2c61c --- /dev/null +++ b/kubernetes-vault/consul/templates/crd-grpcroutes.yaml @@ -0,0 +1,669 @@ +{{- if .Values.connectInject.enabled }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: crd + name: grpcroutes.mesh.consul.hashicorp.com +spec: + group: mesh.consul.hashicorp.com + names: + kind: GRPCRoute + listKind: GRPCRouteList + plural: grpcroutes + shortNames: + - grpc-route + singular: grpcroute + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The sync status of the resource with Consul + jsonPath: .status.conditions[?(@.type=="Synced")].status + name: Synced + type: string + - description: The last successful synced time of the resource with Consul + jsonPath: .status.lastSyncedTime + name: Last Synced + type: date + - description: The age of the resource + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v2beta1 + schema: + openAPIV3Schema: + description: GRPCRoute is the Schema for the GRPC Route 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: |- + NOTE: this should align to the GAMMA/gateway-api version, or at least be + easily translatable. + + + https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1alpha2.GRPCRoute + + + This is a Resource type. + properties: + hostnames: + description: |- + Hostnames are the hostnames for which this GRPCRoute should respond to requests. + + + This is only valid for north/south. + items: + type: string + type: array + parentRefs: + description: |- + ParentRefs references the resources (usually Services) that a Route wants + to be attached to. + + + It is invalid to reference an identical parent more than once. It is valid + to reference multiple distinct sections within the same parent resource. + items: + description: 'NOTE: roughly equivalent to structs.ResourceReference' + properties: + port: + description: |- + For east/west this is the name of the Consul Service port to direct traffic to + or empty to imply all. + For north/south this is TBD. + + + For more details on potential values of this field, see documentation for + Service.ServicePort. + type: string + ref: + description: |- + For east/west configuration, this should point to a Service. + For north/south it should point to a Gateway. + properties: + name: + description: Name is the user-given name of the resource + (e.g. the "billing" service). + type: string + section: + description: Section identifies which part of the resource + the condition relates to. + type: string + tenancy: + description: |- + Tenancy identifies the tenancy units (i.e. partition, namespace) in which + the resource resides. + properties: + namespace: + description: |- + Namespace further isolates resources within a partition. + https://developer.hashicorp.com/consul/docs/enterprise/namespaces + + + When using the List and WatchList endpoints, provide the wildcard value "*" + to list resources across all namespaces. + type: string + partition: + description: |- + Partition is the topmost administrative boundary within a cluster. + https://developer.hashicorp.com/consul/docs/enterprise/admin-partitions + + + When using the List and WatchList endpoints, provide the wildcard value "*" + to list resources across all partitions. + type: string + type: object + type: + description: Type identifies the resource's type. + properties: + group: + description: |- + Group describes the area of functionality to which this resource type + relates (e.g. "catalog", "authorization"). + type: string + groupVersion: + description: |- + GroupVersion is incremented when sweeping or backward-incompatible changes + are made to the group's resource types. + type: string + kind: + description: Kind identifies the specific resource type + within the group. + type: string + type: object + type: object + type: object + type: array + rules: + description: Rules are a list of GRPC matchers, filters and actions. + items: + properties: + backendRefs: + description: |- + BackendRefs defines the backend(s) where matching requests should be sent. + Failure behavior here depends on how many BackendRefs are specified and + how many are invalid. + + + 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. + + + See the GRPCBackendRef definition for the rules about what makes a single + GRPCBackendRef invalid. + + + When a GRPCBackendRef 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. + + + 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. + items: + properties: + backendRef: + properties: + datacenter: + type: string + port: + description: |- + For east/west this is the name of the Consul Service port to direct traffic to + or empty to imply using the same value as the parent ref. + For north/south this is TBD. + + + For more details on potential values of this field, see documentation for + Service.ServicePort. + type: string + ref: + description: For east/west configuration, this should + point to a Service. + properties: + name: + description: Name is the user-given name of the + resource (e.g. the "billing" service). + type: string + section: + description: Section identifies which part of + the resource the condition relates to. + type: string + tenancy: + description: |- + Tenancy identifies the tenancy units (i.e. partition, namespace) in which + the resource resides. + properties: + namespace: + description: |- + Namespace further isolates resources within a partition. + https://developer.hashicorp.com/consul/docs/enterprise/namespaces + + + When using the List and WatchList endpoints, provide the wildcard value "*" + to list resources across all namespaces. + type: string + partition: + description: |- + Partition is the topmost administrative boundary within a cluster. + https://developer.hashicorp.com/consul/docs/enterprise/admin-partitions + + + When using the List and WatchList endpoints, provide the wildcard value "*" + to list resources across all partitions. + type: string + type: object + type: + description: Type identifies the resource's type. + properties: + group: + description: |- + Group describes the area of functionality to which this resource type + relates (e.g. "catalog", "authorization"). + type: string + groupVersion: + description: |- + GroupVersion is incremented when sweeping or backward-incompatible changes + are made to the group's resource types. + type: string + kind: + description: Kind identifies the specific + resource type within the group. + type: string + type: object + type: object + type: object + filters: + description: |- + Filters defined at this level should be executed if and only if the + request is being forwarded to the backend defined here. + items: + properties: + requestHeaderModifier: + description: |- + RequestHeaderModifier defines a schema for a filter that modifies request + headers. + 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. + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + 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). + items: + type: string + type: array + set: + description: |- + Set overwrites the request with the given header (name, value) before the + action. + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + type: object + responseHeaderModifier: + description: |- + ResponseHeaderModifier defines a schema for a filter that modifies + response headers. + 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. + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + 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). + items: + type: string + type: array + set: + description: |- + Set overwrites the request with the given header (name, value) before the + action. + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + type: object + urlRewrite: + description: |- + URLRewrite defines a schema for a filter that modifies a request during + forwarding. + properties: + pathPrefix: + type: string + type: object + type: object + type: array + weight: + 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. + + + 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. + format: int32 + type: integer + type: object + type: array + filters: + items: + properties: + requestHeaderModifier: + description: |- + RequestHeaderModifier defines a schema for a filter that modifies request + headers. + 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. + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + 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). + items: + type: string + type: array + set: + description: |- + Set overwrites the request with the given header (name, value) before the + action. + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + type: object + responseHeaderModifier: + description: |- + ResponseHeaderModifier defines a schema for a filter that modifies + response headers. + 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. + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + 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). + items: + type: string + type: array + set: + description: |- + Set overwrites the request with the given header (name, value) before the + action. + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + type: object + urlRewrite: + description: |- + URLRewrite defines a schema for a filter that modifies a request during + forwarding. + properties: + pathPrefix: + type: string + type: object + type: object + type: array + matches: + items: + 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: + properties: + name: + type: string + type: + description: |- + HeaderMatchType specifies the semantics of how HTTP header values should be + compared. Valid HeaderMatchType values, along with their conformance levels, + are: + + + Note that values may be added to this enum, implementations must ensure that + unknown values will not cause a crash. + + + Unknown values here must result in the implementation setting the Accepted + Condition for the Route to status: False, with a Reason of UnsupportedValue. + enum: + - HEADER_MATCH_TYPE_UNSPECIFIED + - HEADER_MATCH_TYPE_EXACT + - HEADER_MATCH_TYPE_REGEX + - HEADER_MATCH_TYPE_PRESENT + - HEADER_MATCH_TYPE_PREFIX + - HEADER_MATCH_TYPE_SUFFIX + format: int32 + type: string + value: + type: string + type: object + type: array + 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. + + + At least one of Service and Method MUST be a non-empty string.} + type: string + service: + description: |- + Value of the service to match against. If left empty or omitted, will + match any service. + + + At least one of Service and Method MUST be a non-empty string. + type: string + type: + description: |- + Type specifies how to match against the service and/or method. Support: + Core (Exact with service and method specified) + enum: + - GRPC_METHOD_MATCH_TYPE_UNSPECIFIED + - GRPC_METHOD_MATCH_TYPE_EXACT + - GRPC_METHOD_MATCH_TYPE_REGEX + format: int32 + type: string + type: object + type: object + type: array + retries: + properties: + number: + description: |- + Number is the number of times to retry the request when a retryable + result occurs. + properties: + value: + description: The uint32 value. + format: int32 + type: integer + type: object + onConditions: + description: |- + RetryOn allows setting envoy specific conditions when a request should + be automatically retried. + items: + type: string + type: array + onConnectFailure: + description: |- + RetryOnConnectFailure allows for connection failure errors to trigger a + retry. + type: boolean + onStatusCodes: + description: |- + RetryOnStatusCodes is a flat list of http response status codes that are + eligible for retry. This again should be feasible in any reasonable proxy. + items: + format: int32 + type: integer + type: array + type: object + timeouts: + description: |- + HTTPRouteTimeouts defines timeouts that can be configured for an HTTPRoute + or GRPCRoute. + properties: + idle: + description: Idle specifies the total amount of time permitted + for the request stream to be idle. + format: duration + properties: + nanos: + description: |- + Signed fractions of a second at nanosecond resolution of the span + of time. Durations less than one second are represented with a 0 + `seconds` field and a positive or negative `nanos` field. For durations + of one second or more, a non-zero value for the `nanos` field must be + of the same sign as the `seconds` field. Must be from -999,999,999 + to +999,999,999 inclusive. + format: int32 + type: integer + seconds: + description: |- + Signed seconds of the span of time. Must be from -315,576,000,000 + to +315,576,000,000 inclusive. Note: these bounds are computed from: + 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years + format: int64 + type: integer + type: object + request: + description: |- + RequestTimeout is the total amount of time permitted for the entire + downstream request (and retries) to be processed. + format: duration + properties: + nanos: + description: |- + Signed fractions of a second at nanosecond resolution of the span + of time. Durations less than one second are represented with a 0 + `seconds` field and a positive or negative `nanos` field. For durations + of one second or more, a non-zero value for the `nanos` field must be + of the same sign as the `seconds` field. Must be from -999,999,999 + to +999,999,999 inclusive. + format: int32 + type: integer + seconds: + description: |- + Signed seconds of the span of time. Must be from -315,576,000,000 + to +315,576,000,000 inclusive. Note: these bounds are computed from: + 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years + format: int64 + type: integer + type: object + type: object + type: object + type: array + type: object + status: + properties: + conditions: + description: Conditions indicate the latest available observations + of a resource's current state. + items: + description: |- + Conditions define a readiness condition for a Consul resource. + See: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties + properties: + lastTransitionTime: + description: LastTransitionTime is the 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 condition. + type: string + required: + - status + - type + type: object + type: array + lastSyncedTime: + description: LastSyncedTime is the last time the resource successfully + synced with Consul. + format: date-time + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- end }} diff --git a/kubernetes-vault/consul/templates/crd-httproutes-external.yaml b/kubernetes-vault/consul/templates/crd-httproutes-external.yaml new file mode 100644 index 0000000..bba3672 --- /dev/null +++ b/kubernetes-vault/consul/templates/crd-httproutes-external.yaml @@ -0,0 +1,1914 @@ +{{- if and .Values.connectInject.enabled .Values.connectInject.apiGateway.manageExternalCRDs }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/1538 + gateway.networking.k8s.io/bundle-version: v0.6.2 + gateway.networking.k8s.io/channel: experimental + creationTimestamp: null + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: crd + 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 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 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: 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 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 + 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 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 \n " + properties: + replaceFullPath: + description: "ReplaceFullPath specifies the value with which to replace the full path of a request during a rewrite or redirect. \n " + 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. \n " + 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`. \n " + 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 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 \n " + 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`. \n " + 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 \n " + properties: + hostname: + description: "Hostname is the value to be used to replace the Host header value during forwarding. \n Support: Extended \n " + 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 \n " + properties: + replaceFullPath: + description: "ReplaceFullPath specifies the value with which to replace the full path of a request during a rewrite or redirect. \n " + 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. \n " + 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`. \n " + 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 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 + 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 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 + 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 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 \n " + properties: + replaceFullPath: + description: "ReplaceFullPath specifies the value with which to replace the full path of a request during a rewrite or redirect. \n " + 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. \n " + 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`. \n " + 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 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 \n " + 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`. \n " + 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 \n " + properties: + hostname: + description: "Hostname is the value to be used to replace the Host header value during forwarding. \n Support: Extended \n " + 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 \n " + properties: + replaceFullPath: + description: "ReplaceFullPath specifies the value with which to replace the full path of a request during a rewrite or redirect. \n " + 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. \n " + 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`. \n " + 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 with the largest number of: \n * 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 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 \tpath: \t value: \"/foo\" \theaders: \t- name: \"version\" \t 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 + 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 \ttype FooStatus struct{ \t // Represents the observations of a foo's current state. \t // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" \t // +patchMergeKey=type \t // +patchStrategy=merge \t // +listType=map \t // +listMapKey=type \t Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n \t // other fields \t}" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + 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 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 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: 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 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 + 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 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 \n " + properties: + replaceFullPath: + description: "ReplaceFullPath specifies the value with which to replace the full path of a request during a rewrite or redirect. \n " + 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. \n " + 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`. \n " + 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 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 \n " + 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`. \n " + 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 \n " + properties: + hostname: + description: "Hostname is the value to be used to replace the Host header value during forwarding. \n Support: Extended \n " + 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 \n " + properties: + replaceFullPath: + description: "ReplaceFullPath specifies the value with which to replace the full path of a request during a rewrite or redirect. \n " + 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. \n " + 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`. \n " + 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 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 + 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 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 + 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 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 \n " + properties: + replaceFullPath: + description: "ReplaceFullPath specifies the value with which to replace the full path of a request during a rewrite or redirect. \n " + 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. \n " + 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`. \n " + 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 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 \n " + 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`. \n " + 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 \n " + properties: + hostname: + description: "Hostname is the value to be used to replace the Host header value during forwarding. \n Support: Extended \n " + 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 \n " + properties: + replaceFullPath: + description: "ReplaceFullPath specifies the value with which to replace the full path of a request during a rewrite or redirect. \n " + 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. \n " + 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`. \n " + 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 with the largest number of: \n * 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 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 \tpath: \t value: \"/foo\" \theaders: \t- name: \"version\" \t 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 + 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 \ttype FooStatus struct{ \t // Represents the observations of a foo's current state. \t // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" \t // +patchMergeKey=type \t // +patchStrategy=merge \t // +listType=map \t // +listMapKey=type \t Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n \t // other fields \t}" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + 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: [] + storedVersions: [] +{{- end }} diff --git a/kubernetes-vault/consul/templates/crd-httproutes.yaml b/kubernetes-vault/consul/templates/crd-httproutes.yaml new file mode 100644 index 0000000..a782647 --- /dev/null +++ b/kubernetes-vault/consul/templates/crd-httproutes.yaml @@ -0,0 +1,726 @@ +{{- if .Values.connectInject.enabled }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: crd + name: httproutes.mesh.consul.hashicorp.com +spec: + group: mesh.consul.hashicorp.com + names: + kind: HTTPRoute + listKind: HTTPRouteList + plural: httproutes + shortNames: + - http-route + singular: httproute + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The sync status of the resource with Consul + jsonPath: .status.conditions[?(@.type=="Synced")].status + name: Synced + type: string + - description: The last successful synced time of the resource with Consul + jsonPath: .status.lastSyncedTime + name: Last Synced + type: date + - description: The age of the resource + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v2beta1 + schema: + openAPIV3Schema: + description: HTTPRoute is the Schema for the HTTP Route 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: |- + NOTE: this should align to the GAMMA/gateway-api version, or at least be + easily translatable. + + + https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1alpha2.HTTPRoute + + + This is a Resource type. + properties: + hostnames: + description: |- + Hostnames are the hostnames for which this HTTPRoute should respond to requests. + + + This is only valid for north/south. + items: + type: string + type: array + parentRefs: + description: |- + ParentRefs references the resources (usually Services) that a Route wants + to be attached to. + + + It is invalid to reference an identical parent more than once. It is valid + to reference multiple distinct sections within the same parent resource. + items: + description: 'NOTE: roughly equivalent to structs.ResourceReference' + properties: + port: + description: |- + For east/west this is the name of the Consul Service port to direct traffic to + or empty to imply all. + For north/south this is TBD. + + + For more details on potential values of this field, see documentation for + Service.ServicePort. + type: string + ref: + description: |- + For east/west configuration, this should point to a Service. + For north/south it should point to a Gateway. + properties: + name: + description: Name is the user-given name of the resource + (e.g. the "billing" service). + type: string + section: + description: Section identifies which part of the resource + the condition relates to. + type: string + tenancy: + description: |- + Tenancy identifies the tenancy units (i.e. partition, namespace) in which + the resource resides. + properties: + namespace: + description: |- + Namespace further isolates resources within a partition. + https://developer.hashicorp.com/consul/docs/enterprise/namespaces + + + When using the List and WatchList endpoints, provide the wildcard value "*" + to list resources across all namespaces. + type: string + partition: + description: |- + Partition is the topmost administrative boundary within a cluster. + https://developer.hashicorp.com/consul/docs/enterprise/admin-partitions + + + When using the List and WatchList endpoints, provide the wildcard value "*" + to list resources across all partitions. + type: string + type: object + type: + description: Type identifies the resource's type. + properties: + group: + description: |- + Group describes the area of functionality to which this resource type + relates (e.g. "catalog", "authorization"). + type: string + groupVersion: + description: |- + GroupVersion is incremented when sweeping or backward-incompatible changes + are made to the group's resource types. + type: string + kind: + description: Kind identifies the specific resource type + within the group. + type: string + type: object + type: object + type: object + type: array + rules: + description: |- + Rules are a list of HTTP-based routing rules that this route should + use for constructing a routing table. + items: + description: |- + HTTPRouteRule specifies the routing rules used to determine what upstream + service an HTTP request is routed to. + properties: + backendRefs: + description: |- + BackendRefs defines the backend(s) where matching requests should be sent. + + + Failure behavior here depends on how many BackendRefs are specified and + how many are invalid. + + + 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. + + + See the HTTPBackendRef definition for the rules about what makes a single + HTTPBackendRef invalid. + + + 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. + + + 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. + items: + properties: + backendRef: + properties: + datacenter: + type: string + port: + description: |- + For east/west this is the name of the Consul Service port to direct traffic to + or empty to imply using the same value as the parent ref. + For north/south this is TBD. + + + For more details on potential values of this field, see documentation for + Service.ServicePort. + type: string + ref: + description: For east/west configuration, this should + point to a Service. + properties: + name: + description: Name is the user-given name of the + resource (e.g. the "billing" service). + type: string + section: + description: Section identifies which part of + the resource the condition relates to. + type: string + tenancy: + description: |- + Tenancy identifies the tenancy units (i.e. partition, namespace) in which + the resource resides. + properties: + namespace: + description: |- + Namespace further isolates resources within a partition. + https://developer.hashicorp.com/consul/docs/enterprise/namespaces + + + When using the List and WatchList endpoints, provide the wildcard value "*" + to list resources across all namespaces. + type: string + partition: + description: |- + Partition is the topmost administrative boundary within a cluster. + https://developer.hashicorp.com/consul/docs/enterprise/admin-partitions + + + When using the List and WatchList endpoints, provide the wildcard value "*" + to list resources across all partitions. + type: string + type: object + type: + description: Type identifies the resource's type. + properties: + group: + description: |- + Group describes the area of functionality to which this resource type + relates (e.g. "catalog", "authorization"). + type: string + groupVersion: + description: |- + GroupVersion is incremented when sweeping or backward-incompatible changes + are made to the group's resource types. + type: string + kind: + description: Kind identifies the specific + resource type within the group. + type: string + type: object + type: object + type: object + filters: + description: |- + Filters defined at this level should be executed if and only if the + request is being forwarded to the backend defined here. + items: + properties: + requestHeaderModifier: + description: |- + RequestHeaderModifier defines a schema for a filter that modifies request + headers. + 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. + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + 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). + items: + type: string + type: array + set: + description: |- + Set overwrites the request with the given header (name, value) before the + action. + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + type: object + responseHeaderModifier: + description: |- + ResponseHeaderModifier defines a schema for a filter that modifies + response headers. + 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. + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + 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). + items: + type: string + type: array + set: + description: |- + Set overwrites the request with the given header (name, value) before the + action. + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + type: object + urlRewrite: + description: |- + URLRewrite defines a schema for a filter that modifies a request during + forwarding. + properties: + pathPrefix: + type: string + type: object + type: object + type: array + weight: + 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. + + + 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. + format: int32 + type: integer + type: object + type: array + filters: + items: + properties: + requestHeaderModifier: + description: |- + RequestHeaderModifier defines a schema for a filter that modifies request + headers. + 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. + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + 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). + items: + type: string + type: array + set: + description: |- + Set overwrites the request with the given header (name, value) before the + action. + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + type: object + responseHeaderModifier: + description: |- + ResponseHeaderModifier defines a schema for a filter that modifies + response headers. + 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. + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + 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). + items: + type: string + type: array + set: + description: |- + Set overwrites the request with the given header (name, value) before the + action. + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + type: object + urlRewrite: + description: |- + URLRewrite defines a schema for a filter that modifies a request during + forwarding. + properties: + pathPrefix: + type: string + type: object + type: object + type: array + matches: + items: + 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: + properties: + invert: + description: 'NOTE: not in gamma; service-router + compat' + type: boolean + 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). + + + 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. + + + 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”. + type: string + type: + description: Type specifies how to match against + the value of the header. + enum: + - HEADER_MATCH_TYPE_UNSPECIFIED + - HEADER_MATCH_TYPE_EXACT + - HEADER_MATCH_TYPE_REGEX + - HEADER_MATCH_TYPE_PRESENT + - HEADER_MATCH_TYPE_PREFIX + - HEADER_MATCH_TYPE_SUFFIX + format: int32 + type: string + value: + description: Value is the value of HTTP Header to + be matched. + type: string + type: object + type: array + method: + description: |- + Method specifies HTTP method matcher. When specified, this route will be + matched only if the request has the specified method. + type: string + path: + 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: + description: Type specifies how to match against the + path Value. + enum: + - PATH_MATCH_TYPE_UNSPECIFIED + - PATH_MATCH_TYPE_EXACT + - PATH_MATCH_TYPE_PREFIX + - PATH_MATCH_TYPE_REGEX + format: int32 + type: string + value: + description: Value of the HTTP path to match against. + 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: + 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). + + + 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. + + + 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. + + + Users SHOULD NOT route traffic based on repeated query params to guard + themselves against potential differences in the implementations. + type: string + type: + description: Type specifies how to match against + the value of the query parameter. + enum: + - QUERY_PARAM_MATCH_TYPE_UNSPECIFIED + - QUERY_PARAM_MATCH_TYPE_EXACT + - QUERY_PARAM_MATCH_TYPE_REGEX + - QUERY_PARAM_MATCH_TYPE_PRESENT + format: int32 + type: string + value: + description: Value is the value of HTTP query param + to be matched. + type: string + type: object + type: array + type: object + type: array + retries: + properties: + number: + description: |- + Number is the number of times to retry the request when a retryable + result occurs. + properties: + value: + description: The uint32 value. + format: int32 + type: integer + type: object + onConditions: + description: |- + RetryOn allows setting envoy specific conditions when a request should + be automatically retried. + items: + type: string + type: array + onConnectFailure: + description: |- + RetryOnConnectFailure allows for connection failure errors to trigger a + retry. + type: boolean + onStatusCodes: + description: |- + RetryOnStatusCodes is a flat list of http response status codes that are + eligible for retry. This again should be feasible in any reasonable proxy. + items: + format: int32 + type: integer + type: array + type: object + timeouts: + description: |- + HTTPRouteTimeouts defines timeouts that can be configured for an HTTPRoute + or GRPCRoute. + properties: + idle: + description: Idle specifies the total amount of time permitted + for the request stream to be idle. + format: duration + properties: + nanos: + description: |- + Signed fractions of a second at nanosecond resolution of the span + of time. Durations less than one second are represented with a 0 + `seconds` field and a positive or negative `nanos` field. For durations + of one second or more, a non-zero value for the `nanos` field must be + of the same sign as the `seconds` field. Must be from -999,999,999 + to +999,999,999 inclusive. + format: int32 + type: integer + seconds: + description: |- + Signed seconds of the span of time. Must be from -315,576,000,000 + to +315,576,000,000 inclusive. Note: these bounds are computed from: + 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years + format: int64 + type: integer + type: object + request: + description: |- + RequestTimeout is the total amount of time permitted for the entire + downstream request (and retries) to be processed. + format: duration + properties: + nanos: + description: |- + Signed fractions of a second at nanosecond resolution of the span + of time. Durations less than one second are represented with a 0 + `seconds` field and a positive or negative `nanos` field. For durations + of one second or more, a non-zero value for the `nanos` field must be + of the same sign as the `seconds` field. Must be from -999,999,999 + to +999,999,999 inclusive. + format: int32 + type: integer + seconds: + description: |- + Signed seconds of the span of time. Must be from -315,576,000,000 + to +315,576,000,000 inclusive. Note: these bounds are computed from: + 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years + format: int64 + type: integer + type: object + type: object + type: object + type: array + type: object + status: + properties: + conditions: + description: Conditions indicate the latest available observations + of a resource's current state. + items: + description: |- + Conditions define a readiness condition for a Consul resource. + See: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties + properties: + lastTransitionTime: + description: LastTransitionTime is the 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 condition. + type: string + required: + - status + - type + type: object + type: array + lastSyncedTime: + description: LastSyncedTime is the last time the resource successfully + synced with Consul. + format: date-time + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- end }} diff --git a/kubernetes-vault/consul/templates/crd-ingressgateways.yaml b/kubernetes-vault/consul/templates/crd-ingressgateways.yaml new file mode 100644 index 0000000..53649c8 --- /dev/null +++ b/kubernetes-vault/consul/templates/crd-ingressgateways.yaml @@ -0,0 +1,466 @@ +{{- if .Values.connectInject.enabled }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: crd + name: ingressgateways.consul.hashicorp.com +spec: + group: consul.hashicorp.com + names: + kind: IngressGateway + listKind: IngressGatewayList + plural: ingressgateways + shortNames: + - ingress-gateway + singular: ingressgateway + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The sync status of the resource with Consul + jsonPath: .status.conditions[?(@.type=="Synced")].status + name: Synced + type: string + - description: The last successful synced time of the resource with Consul + jsonPath: .status.lastSyncedTime + name: Last Synced + type: date + - description: The age of the resource + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: IngressGateway is the Schema for the ingressgateways 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: IngressGatewaySpec defines the desired state of IngressGateway. + properties: + defaults: + description: Defaults is default configuration for all upstream services + properties: + maxConcurrentRequests: + description: |- + The maximum number of concurrent requests that + will be allowed at a single point in time. Use this to limit HTTP/2 traffic, + since HTTP/2 has many requests per connection. + format: int32 + type: integer + maxConnections: + description: |- + The maximum number of connections a service instance + will be allowed to establish against the given upstream. Use this to limit + HTTP/1.1 traffic, since HTTP/1.1 has a request per connection. + format: int32 + type: integer + maxPendingRequests: + description: |- + The maximum number of requests that will be queued + while waiting for a connection to be established. + format: int32 + type: integer + passiveHealthCheck: + description: |- + PassiveHealthCheck configuration determines how upstream proxy instances will + be monitored for removal from the load balancing pool. + properties: + baseEjectionTime: + description: |- + The base time that a host is ejected for. The real time is equal to the base time + multiplied by the number of times the host has been ejected and is capped by + max_ejection_time (Default 300s). Defaults to 30s. + type: string + enforcingConsecutive5xx: + description: |- + EnforcingConsecutive5xx is the % chance that a host will be actually ejected + when an outlier status is detected through consecutive 5xx. + This setting can be used to disable ejection or to ramp it up slowly. + Ex. Setting this to 10 will make it a 10% chance that the host will be ejected. + format: int32 + type: integer + interval: + description: |- + Interval between health check analysis sweeps. Each sweep may remove + hosts or return hosts to the pool. Ex. setting this to "10s" will set + the interval to 10 seconds. + type: string + maxEjectionPercent: + description: |- + The maximum % of an upstream cluster that can be ejected due to outlier detection. + Defaults to 10% but will eject at least one host regardless of the value. + format: int32 + type: integer + maxFailures: + description: |- + MaxFailures is the count of consecutive failures that results in a host + being removed from the pool. + format: int32 + type: integer + type: object + type: object + listeners: + description: |- + Listeners declares what ports the ingress gateway should listen on, and + what services to associated to those ports. + items: + description: IngressListener manages the configuration for a listener + on a specific port. + properties: + port: + description: Port declares the port on which the ingress gateway + should listen for traffic. + type: integer + protocol: + description: |- + Protocol declares what type of traffic this listener is expected to + receive. Depending on the protocol, a listener might support multiplexing + services over a single port, or additional discovery chain features. The + current supported values are: (tcp | http | http2 | grpc). + type: string + services: + description: |- + Services declares the set of services to which the listener forwards + traffic. + For "tcp" protocol listeners, only a single service is allowed. + For "http" listeners, multiple services can be declared. + items: + description: |- + IngressService manages configuration for services that are exposed to + ingress traffic. + properties: + hosts: + description: |- + Hosts is a list of hostnames which should be associated to this service on + the defined listener. Only allowed on layer 7 protocols, this will be used + to route traffic to the service by matching the Host header of the HTTP + request. + + + If a host is provided for a service that also has a wildcard specifier + defined, the host will override the wildcard-specifier-provided + ".*" domain for that listener. + + + This cannot be specified when using the wildcard specifier, "*", or when + using a "tcp" listener. + items: + type: string + type: array + maxConcurrentRequests: + description: |- + The maximum number of concurrent requests that + will be allowed at a single point in time. Use this to limit HTTP/2 traffic, + since HTTP/2 has many requests per connection. + format: int32 + type: integer + maxConnections: + description: |- + The maximum number of connections a service instance + will be allowed to establish against the given upstream. Use this to limit + HTTP/1.1 traffic, since HTTP/1.1 has a request per connection. + format: int32 + type: integer + maxPendingRequests: + description: |- + The maximum number of requests that will be queued + while waiting for a connection to be established. + format: int32 + type: integer + name: + description: |- + Name declares the service to which traffic should be forwarded. + + + This can either be a specific service, or the wildcard specifier, + "*". If the wildcard specifier is provided, the listener must be of "http" + protocol and means that the listener will forward traffic to all services. + + + A name can be specified on multiple listeners, and will be exposed on both + of the listeners. + type: string + namespace: + description: |- + Namespace is the namespace where the service is located. + Namespacing is a Consul Enterprise feature. + type: string + partition: + description: |- + Partition is the admin-partition where the service is located. + Partitioning is a Consul Enterprise feature. + type: string + passiveHealthCheck: + description: |- + PassiveHealthCheck configuration determines how upstream proxy instances will + be monitored for removal from the load balancing pool. + properties: + baseEjectionTime: + description: |- + The base time that a host is ejected for. The real time is equal to the base time + multiplied by the number of times the host has been ejected and is capped by + max_ejection_time (Default 300s). Defaults to 30s. + type: string + enforcingConsecutive5xx: + description: |- + EnforcingConsecutive5xx is the % chance that a host will be actually ejected + when an outlier status is detected through consecutive 5xx. + This setting can be used to disable ejection or to ramp it up slowly. + Ex. Setting this to 10 will make it a 10% chance that the host will be ejected. + format: int32 + type: integer + interval: + description: |- + Interval between health check analysis sweeps. Each sweep may remove + hosts or return hosts to the pool. Ex. setting this to "10s" will set + the interval to 10 seconds. + type: string + maxEjectionPercent: + description: |- + The maximum % of an upstream cluster that can be ejected due to outlier detection. + Defaults to 10% but will eject at least one host regardless of the value. + format: int32 + type: integer + maxFailures: + description: |- + MaxFailures is the count of consecutive failures that results in a host + being removed from the pool. + format: int32 + type: integer + type: object + requestHeaders: + description: Allow HTTP header manipulation to be configured. + properties: + add: + additionalProperties: + type: string + description: |- + Add is a set of name -> value pairs that should be appended to the request + or response (i.e. allowing duplicates if the same header already exists). + type: object + remove: + description: |- + Remove is the set of header names that should be stripped from the request + or response. + items: + type: string + type: array + set: + additionalProperties: + type: string + description: |- + Set is a set of name -> value pairs that should be added to the request or + response, overwriting any existing header values of the same name. + type: object + type: object + responseHeaders: + description: |- + HTTPHeaderModifiers is a set of rules for HTTP header modification that + should be performed by proxies as the request passes through them. It can + operate on either request or response headers depending on the context in + which it is used. + properties: + add: + additionalProperties: + type: string + description: |- + Add is a set of name -> value pairs that should be appended to the request + or response (i.e. allowing duplicates if the same header already exists). + type: object + remove: + description: |- + Remove is the set of header names that should be stripped from the request + or response. + items: + type: string + type: array + set: + additionalProperties: + type: string + description: |- + Set is a set of name -> value pairs that should be added to the request or + response, overwriting any existing header values of the same name. + type: object + type: object + tls: + description: TLS allows specifying some TLS configuration + per listener. + properties: + sds: + description: SDS allows configuring TLS certificate + from an SDS service. + properties: + certResource: + description: CertResource is the SDS resource + name to request when fetching the certificate + from the SDS service. + type: string + clusterName: + description: |- + ClusterName is the SDS cluster name to connect to, to retrieve certificates. + This cluster must be specified in the Gateway's bootstrap configuration. + type: string + type: object + type: object + type: object + type: array + tls: + description: TLS config for this listener. + properties: + cipherSuites: + description: |- + Define a subset of cipher suites to restrict + Only applicable to connections negotiated via TLS 1.2 or earlier. + items: + type: string + type: array + enabled: + description: Indicates that TLS should be enabled for this + gateway service. + type: boolean + sds: + description: SDS allows configuring TLS certificate from + an SDS service. + properties: + certResource: + description: CertResource is the SDS resource name to + request when fetching the certificate from the SDS + service. + type: string + clusterName: + description: |- + ClusterName is the SDS cluster name to connect to, to retrieve certificates. + This cluster must be specified in the Gateway's bootstrap configuration. + type: string + type: object + tlsMaxVersion: + description: |- + TLSMaxVersion sets the default maximum TLS version supported. Must be greater than or equal to `TLSMinVersion`. + One of `TLS_AUTO`, `TLSv1_0`, `TLSv1_1`, `TLSv1_2`, or `TLSv1_3`. + If unspecified, Envoy will default to TLS 1.3 as a max version for incoming connections. + type: string + tlsMinVersion: + description: |- + TLSMinVersion sets the default minimum TLS version supported. + One of `TLS_AUTO`, `TLSv1_0`, `TLSv1_1`, `TLSv1_2`, or `TLSv1_3`. + If unspecified, Envoy v1.22.0 and newer will default to TLS 1.2 as a min version, + while older releases of Envoy default to TLS 1.0. + type: string + required: + - enabled + type: object + type: object + type: array + tls: + description: TLS holds the TLS configuration for this gateway. + properties: + cipherSuites: + description: |- + Define a subset of cipher suites to restrict + Only applicable to connections negotiated via TLS 1.2 or earlier. + items: + type: string + type: array + enabled: + description: Indicates that TLS should be enabled for this gateway + service. + type: boolean + sds: + description: SDS allows configuring TLS certificate from an SDS + service. + properties: + certResource: + description: CertResource is the SDS resource name to request + when fetching the certificate from the SDS service. + type: string + clusterName: + description: |- + ClusterName is the SDS cluster name to connect to, to retrieve certificates. + This cluster must be specified in the Gateway's bootstrap configuration. + type: string + type: object + tlsMaxVersion: + description: |- + TLSMaxVersion sets the default maximum TLS version supported. Must be greater than or equal to `TLSMinVersion`. + One of `TLS_AUTO`, `TLSv1_0`, `TLSv1_1`, `TLSv1_2`, or `TLSv1_3`. + If unspecified, Envoy will default to TLS 1.3 as a max version for incoming connections. + type: string + tlsMinVersion: + description: |- + TLSMinVersion sets the default minimum TLS version supported. + One of `TLS_AUTO`, `TLSv1_0`, `TLSv1_1`, `TLSv1_2`, or `TLSv1_3`. + If unspecified, Envoy v1.22.0 and newer will default to TLS 1.2 as a min version, + while older releases of Envoy default to TLS 1.0. + type: string + required: + - enabled + type: object + type: object + status: + properties: + conditions: + description: Conditions indicate the latest available observations + of a resource's current state. + items: + description: |- + Conditions define a readiness condition for a Consul resource. + See: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties + properties: + lastTransitionTime: + description: LastTransitionTime is the 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 condition. + type: string + required: + - status + - type + type: object + type: array + lastSyncedTime: + description: LastSyncedTime is the last time the resource successfully + synced with Consul. + format: date-time + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- end }} diff --git a/kubernetes-vault/consul/templates/crd-jwtproviders.yaml b/kubernetes-vault/consul/templates/crd-jwtproviders.yaml new file mode 100644 index 0000000..b52d77b --- /dev/null +++ b/kubernetes-vault/consul/templates/crd-jwtproviders.yaml @@ -0,0 +1,375 @@ +{{- if .Values.connectInject.enabled }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: crd + name: jwtproviders.consul.hashicorp.com +spec: + group: consul.hashicorp.com + names: + kind: JWTProvider + listKind: JWTProviderList + plural: jwtproviders + singular: jwtprovider + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: JWTProvider is the Schema for the jwtproviders 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: JWTProviderSpec defines the desired state of JWTProvider + properties: + audiences: + description: |- + Audiences is the set of audiences the JWT is allowed to access. + If specified, all JWTs verified with this provider must address + at least one of these to be considered valid. + items: + type: string + type: array + cacheConfig: + description: |- + CacheConfig defines configuration for caching the validation + result for previously seen JWTs. Caching results can speed up + verification when individual tokens are expected to be handled + multiple times. + properties: + size: + description: |- + Size specifies the maximum number of JWT verification + results to cache. + + + Defaults to 0, meaning that JWT caching is disabled. + type: integer + type: object + clockSkewSeconds: + description: |- + ClockSkewSeconds specifies the maximum allowable time difference + from clock skew when validating the "exp" (Expiration) and "nbf" + (Not Before) claims. + + + Default value is 30 seconds. + type: integer + forwarding: + description: Forwarding defines rules for forwarding verified JWTs + to the backend. + properties: + headerName: + description: |- + HeaderName is a header name to use when forwarding a verified + JWT to the backend. The verified JWT could have been extracted + from any location (query param, header, or cookie). + + + The header value will be base64-URL-encoded, and will not be + padded unless PadForwardPayloadHeader is true. + type: string + padForwardPayloadHeader: + description: |- + PadForwardPayloadHeader determines whether padding should be added + to the base64 encoded token forwarded with ForwardPayloadHeader. + + + Default value is false. + type: boolean + type: object + issuer: + description: |- + Issuer is the entity that must have issued the JWT. + This value must match the "iss" claim of the token. + type: string + jsonWebKeySet: + description: |- + JSONWebKeySet defines a JSON Web Key Set, its location on disk, or the + means with which to fetch a key set from a remote server. + properties: + local: + description: Local specifies a local source for the key set. + properties: + filename: + description: |- + Filename configures a location on disk where the JWKS can be + found. If specified, the file must be present on the disk of ALL + proxies with intentions referencing this provider. + type: string + jwks: + description: JWKS contains a base64 encoded JWKS. + type: string + type: object + remote: + description: Remote specifies how to fetch a key set from a remote + server. + properties: + cacheDuration: + description: |- + CacheDuration is the duration after which cached keys + should be expired. + + + Default value is 5 minutes. + type: string + fetchAsynchronously: + description: |- + FetchAsynchronously indicates that the JWKS should be fetched + when a client request arrives. Client requests will be paused + until the JWKS is fetched. + If false, the proxy listener will wait for the JWKS to be + fetched before being activated. + + + Default value is false. + type: boolean + jwksCluster: + description: JWKSCluster defines how the specified Remote + JWKS URI is to be fetched. + properties: + connectTimeout: + description: |- + The timeout for new network connections to hosts in the cluster. + If not set, a default value of 5s will be used. + type: string + discoveryType: + description: |- + DiscoveryType refers to the service discovery type to use for resolving the cluster. + + + This defaults to STRICT_DNS. + Other options include STATIC, LOGICAL_DNS, EDS or ORIGINAL_DST. + type: string + tlsCertificates: + description: |- + TLSCertificates refers to the data containing certificate authority certificates to use + in verifying a presented peer certificate. + If not specified and a peer certificate is presented it will not be verified. + + + Must be either CaCertificateProviderInstance or TrustedCA. + properties: + caCertificateProviderInstance: + description: CaCertificateProviderInstance Certificate + provider instance for fetching TLS certificates. + properties: + certificateName: + description: |- + CertificateName is used to specify certificate instances or types. For example, "ROOTCA" to specify + a root-certificate (validation context) or "example.com" to specify a certificate for a + particular domain. + + + The default value is the empty string. + type: string + instanceName: + description: |- + InstanceName refers to the certificate provider instance name. + + + The default value is "default". + type: string + type: object + trustedCA: + description: |- + TrustedCA defines TLS certificate data containing certificate authority certificates + to use in verifying a presented peer certificate. + + + Exactly one of Filename, EnvironmentVariable, InlineString or InlineBytes must be specified. + properties: + environmentVariable: + type: string + filename: + type: string + inlineBytes: + format: byte + type: string + inlineString: + type: string + type: object + type: object + type: object + requestTimeoutMs: + description: |- + RequestTimeoutMs is the number of milliseconds to + time out when making a request for the JWKS. + type: integer + retryPolicy: + description: |- + RetryPolicy defines a retry policy for fetching JWKS. + + + There is no retry by default. + properties: + numRetries: + description: |- + NumRetries is the number of times to retry fetching the JWKS. + The retry strategy uses jittered exponential backoff with + a base interval of 1s and max of 10s. + + + Default value is 0. + type: integer + retryPolicyBackOff: + description: |- + Retry's backoff policy. + + + Defaults to Envoy's backoff policy. + properties: + baseInterval: + description: |- + BaseInterval to be used for the next back off computation. + + + The default value from envoy is 1s. + type: string + maxInterval: + description: |- + MaxInternal to be used to specify the maximum interval between retries. + Optional but should be greater or equal to BaseInterval. + + + Defaults to 10 times BaseInterval. + type: string + type: object + type: object + uri: + description: URI is the URI of the server to query for the + JWKS. + type: string + type: object + type: object + locations: + description: |- + Locations where the JWT will be present in requests. + Envoy will check all of these locations to extract a JWT. + If no locations are specified Envoy will default to: + 1. Authorization header with Bearer schema: + "Authorization: Bearer " + 2. accessToken query parameter. + items: + description: |- + JWTLocation is a location where the JWT could be present in requests. + + + Only one of Header, QueryParam, or Cookie can be specified. + properties: + cookie: + description: Cookie defines how to extract a JWT from an HTTP + request cookie. + properties: + name: + description: Name is the name of the cookie containing the + token. + type: string + type: object + header: + description: Header defines how to extract a JWT from an HTTP + request header. + properties: + forward: + description: |- + Forward defines whether the header with the JWT should be + forwarded after the token has been verified. If false, the + header will not be forwarded to the backend. + + + Default value is false. + type: boolean + name: + description: Name is the name of the header containing the + token. + type: string + valuePrefix: + description: |- + ValuePrefix is an optional prefix that precedes the token in the + header value. + For example, "Bearer " is a standard value prefix for a header named + "Authorization", but the prefix is not part of the token itself: + "Authorization: Bearer " + type: string + type: object + queryParam: + description: |- + QueryParam defines how to extract a JWT from an HTTP request + query parameter. + properties: + name: + description: Name is the name of the query param containing + the token. + type: string + type: object + type: object + type: array + type: object + status: + properties: + conditions: + description: Conditions indicate the latest available observations + of a resource's current state. + items: + description: |- + Conditions define a readiness condition for a Consul resource. + See: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties + properties: + lastTransitionTime: + description: LastTransitionTime is the 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 condition. + type: string + required: + - status + - type + type: object + type: array + lastSyncedTime: + description: LastSyncedTime is the last time the resource successfully + synced with Consul. + format: date-time + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- end }} diff --git a/kubernetes-vault/consul/templates/crd-meshconfigurations.yaml b/kubernetes-vault/consul/templates/crd-meshconfigurations.yaml new file mode 100644 index 0000000..36d644d --- /dev/null +++ b/kubernetes-vault/consul/templates/crd-meshconfigurations.yaml @@ -0,0 +1,107 @@ +{{- if .Values.connectInject.enabled }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: crd + name: meshconfigurations.mesh.consul.hashicorp.com +spec: + group: mesh.consul.hashicorp.com + names: + kind: MeshConfiguration + listKind: MeshConfigurationList + plural: meshconfigurations + singular: meshconfiguration + scope: Cluster + versions: + - additionalPrinterColumns: + - description: The sync status of the resource with Consul + jsonPath: .status.conditions[?(@.type=="Synced")].status + name: Synced + type: string + - description: The last successful synced time of the resource with Consul + jsonPath: .status.lastSyncedTime + name: Last Synced + type: date + - description: The age of the resource + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v2beta1 + schema: + openAPIV3Schema: + description: MeshConfiguration is the Schema for the Mesh Configuration + 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: |- + MeshConfiguration is responsible for configuring the default behavior of Mesh Gateways. + This is a Resource type. + type: object + status: + properties: + conditions: + description: Conditions indicate the latest available observations + of a resource's current state. + items: + description: |- + Conditions define a readiness condition for a Consul resource. + See: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties + properties: + lastTransitionTime: + description: LastTransitionTime is the 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 condition. + type: string + required: + - status + - type + type: object + type: array + lastSyncedTime: + description: LastSyncedTime is the last time the resource successfully + synced with Consul. + format: date-time + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- end }} diff --git a/kubernetes-vault/consul/templates/crd-meshes.yaml b/kubernetes-vault/consul/templates/crd-meshes.yaml new file mode 100644 index 0000000..f81e61a --- /dev/null +++ b/kubernetes-vault/consul/templates/crd-meshes.yaml @@ -0,0 +1,214 @@ +{{- if .Values.connectInject.enabled }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: crd + name: meshes.consul.hashicorp.com +spec: + group: consul.hashicorp.com + names: + kind: Mesh + listKind: MeshList + plural: meshes + singular: mesh + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The sync status of the resource with Consul + jsonPath: .status.conditions[?(@.type=="Synced")].status + name: Synced + type: string + - description: The last successful synced time of the resource with Consul + jsonPath: .status.lastSyncedTime + name: Last Synced + type: date + - description: The age of the resource + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: Mesh is the Schema for the mesh 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: MeshSpec defines the desired state of Mesh. + properties: + allowEnablingPermissiveMutualTLS: + description: |- + AllowEnablingPermissiveMutualTLS must be true in order to allow setting + MutualTLSMode=permissive in either service-defaults or proxy-defaults. + type: boolean + http: + description: HTTP defines the HTTP configuration for the service mesh. + properties: + sanitizeXForwardedClientCert: + type: boolean + required: + - sanitizeXForwardedClientCert + type: object + peering: + description: Peering defines the peering configuration for the service + mesh. + properties: + peerThroughMeshGateways: + description: |- + PeerThroughMeshGateways determines whether peering traffic between + control planes should flow through mesh gateways. If enabled, + Consul servers will advertise mesh gateway addresses as their own. + Additionally, mesh gateways will configure themselves to expose + the local servers using a peering-specific SNI. + type: boolean + type: object + tls: + description: TLS defines the TLS configuration for the service mesh. + properties: + incoming: + description: |- + Incoming defines the TLS configuration for inbound mTLS connections targeting + the public listener on Connect and TerminatingGateway proxy kinds. + properties: + cipherSuites: + description: |- + CipherSuites sets the default list of TLS cipher suites to support when negotiating connections using TLS 1.2 or earlier. + If unspecified, Envoy will use a default server cipher list. The list of supported cipher suites can be seen in + https://github.com/hashicorp/consul/blob/v1.11.2/types/tls.go#L154-L169 and is dependent on underlying support in Envoy. + Future releases of Envoy may remove currently-supported but insecure cipher suites, + and future releases of Consul may add new supported cipher suites if any are added to Envoy. + items: + type: string + type: array + tlsMaxVersion: + description: |- + TLSMaxVersion sets the default maximum TLS version supported. Must be greater than or equal to `TLSMinVersion`. + One of `TLS_AUTO`, `TLSv1_0`, `TLSv1_1`, `TLSv1_2`, or `TLSv1_3`. + If unspecified, Envoy will default to TLS 1.3 as a max version for incoming connections. + type: string + tlsMinVersion: + description: |- + TLSMinVersion sets the default minimum TLS version supported. + One of `TLS_AUTO`, `TLSv1_0`, `TLSv1_1`, `TLSv1_2`, or `TLSv1_3`. + If unspecified, Envoy v1.22.0 and newer will default to TLS 1.2 as a min version, + while older releases of Envoy default to TLS 1.0. + type: string + type: object + outgoing: + description: |- + Outgoing defines the TLS configuration for outbound mTLS connections dialing upstreams + from Connect and IngressGateway proxy kinds. + properties: + cipherSuites: + description: |- + CipherSuites sets the default list of TLS cipher suites to support when negotiating connections using TLS 1.2 or earlier. + If unspecified, Envoy will use a default server cipher list. The list of supported cipher suites can be seen in + https://github.com/hashicorp/consul/blob/v1.11.2/types/tls.go#L154-L169 and is dependent on underlying support in Envoy. + Future releases of Envoy may remove currently-supported but insecure cipher suites, + and future releases of Consul may add new supported cipher suites if any are added to Envoy. + items: + type: string + type: array + tlsMaxVersion: + description: |- + TLSMaxVersion sets the default maximum TLS version supported. Must be greater than or equal to `TLSMinVersion`. + One of `TLS_AUTO`, `TLSv1_0`, `TLSv1_1`, `TLSv1_2`, or `TLSv1_3`. + If unspecified, Envoy will default to TLS 1.3 as a max version for incoming connections. + type: string + tlsMinVersion: + description: |- + TLSMinVersion sets the default minimum TLS version supported. + One of `TLS_AUTO`, `TLSv1_0`, `TLSv1_1`, `TLSv1_2`, or `TLSv1_3`. + If unspecified, Envoy v1.22.0 and newer will default to TLS 1.2 as a min version, + while older releases of Envoy default to TLS 1.0. + type: string + type: object + type: object + transparentProxy: + description: TransparentProxy controls the configuration specific + to proxies in "transparent" mode. Added in v1.10.0. + properties: + meshDestinationsOnly: + description: |- + MeshDestinationsOnly determines whether sidecar proxies operating in "transparent" mode can proxy traffic + to IP addresses not registered in Consul's catalog. If enabled, traffic will only be proxied to upstreams + with service registrations in the catalog. + type: boolean + type: object + validateClusters: + description: |- + ValidateClusters controls whether the clusters the route table refers to are validated. The default value is + false. When set to false and a route refers to a cluster that does not exist, the route table loads and routing + to a non-existent cluster results in a 404. When set to true and the route is set to a cluster that do not exist, + the route table will not load. For more information, refer to + [HTTP route configuration in the Envoy docs](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route.proto#envoy-v3-api-field-config-route-v3-routeconfiguration-validate-clusters) + for more details. + type: boolean + type: object + status: + properties: + conditions: + description: Conditions indicate the latest available observations + of a resource's current state. + items: + description: |- + Conditions define a readiness condition for a Consul resource. + See: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties + properties: + lastTransitionTime: + description: LastTransitionTime is the 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 condition. + type: string + required: + - status + - type + type: object + type: array + lastSyncedTime: + description: LastSyncedTime is the last time the resource successfully + synced with Consul. + format: date-time + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- end }} diff --git a/kubernetes-vault/consul/templates/crd-meshgateways.yaml b/kubernetes-vault/consul/templates/crd-meshgateways.yaml new file mode 100644 index 0000000..553d066 --- /dev/null +++ b/kubernetes-vault/consul/templates/crd-meshgateways.yaml @@ -0,0 +1,140 @@ +{{- if .Values.connectInject.enabled }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: crd + name: meshgateways.mesh.consul.hashicorp.com +spec: + group: mesh.consul.hashicorp.com + names: + kind: MeshGateway + listKind: MeshGatewayList + plural: meshgateways + singular: meshgateway + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The sync status of the resource with Consul + jsonPath: .status.conditions[?(@.type=="Synced")].status + name: Synced + type: string + - description: The last successful synced time of the resource with Consul + jsonPath: .status.lastSyncedTime + name: Last Synced + type: date + - description: The age of the resource + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v2beta1 + schema: + openAPIV3Schema: + description: MeshGateway is the Schema for the Mesh Gateway API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + properties: + gatewayClassName: + description: GatewayClassName is the name of the GatewayClass used + by the MeshGateway + type: string + listeners: + items: + properties: + name: + type: string + port: + format: int32 + maximum: 65535 + minimum: 0 + type: integer + protocol: + enum: + - TCP + type: string + type: object + minItems: 1 + type: array + workloads: + description: Selection of workloads to be configured as mesh gateways + properties: + filter: + type: string + names: + items: + type: string + type: array + prefixes: + items: + type: string + type: array + type: object + type: object + status: + properties: + conditions: + description: Conditions indicate the latest available observations + of a resource's current state. + items: + description: |- + Conditions define a readiness condition for a Consul resource. + See: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties + properties: + lastTransitionTime: + description: LastTransitionTime is the 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 condition. + type: string + required: + - status + - type + type: object + type: array + lastSyncedTime: + description: LastSyncedTime is the last time the resource successfully + synced with Consul. + format: date-time + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- end }} diff --git a/kubernetes-vault/consul/templates/crd-meshservices.yaml b/kubernetes-vault/consul/templates/crd-meshservices.yaml new file mode 100644 index 0000000..1623749 --- /dev/null +++ b/kubernetes-vault/consul/templates/crd-meshservices.yaml @@ -0,0 +1,61 @@ +{{- if .Values.connectInject.enabled }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: crd + name: meshservices.consul.hashicorp.com +spec: + group: consul.hashicorp.com + names: + kind: MeshService + listKind: MeshServiceList + plural: meshservices + singular: meshservice + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: MeshService holds a reference to an externally managed Consul + Service Mesh service. + 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 MeshService. + properties: + name: + description: Name holds the service name for a Consul service. + type: string + peer: + description: |- + Peer optionally specifies the name of the peer exporting the Consul service. + If not specified, the Consul service is assumed to be in the local datacenter. + type: string + type: object + type: object + served: true + storage: true +{{- end }} diff --git a/kubernetes-vault/consul/templates/crd-peeringacceptors.yaml b/kubernetes-vault/consul/templates/crd-peeringacceptors.yaml new file mode 100644 index 0000000..60b31d9 --- /dev/null +++ b/kubernetes-vault/consul/templates/crd-peeringacceptors.yaml @@ -0,0 +1,152 @@ +{{- if and .Values.connectInject.enabled .Values.global.peering.enabled }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: crd + name: peeringacceptors.consul.hashicorp.com +spec: + group: consul.hashicorp.com + names: + kind: PeeringAcceptor + listKind: PeeringAcceptorList + plural: peeringacceptors + shortNames: + - peering-acceptor + singular: peeringacceptor + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The sync status of the resource with Consul + jsonPath: .status.conditions[?(@.type=="Synced")].status + name: Synced + type: string + - description: The last successful synced time of the resource with Consul + jsonPath: .status.lastSyncedTime + name: Last Synced + type: date + - description: The age of the resource + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: PeeringAcceptor is the Schema for the peeringacceptors 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: PeeringAcceptorSpec defines the desired state of PeeringAcceptor. + properties: + peer: + description: Peer describes the information needed to create a peering. + properties: + secret: + description: Secret describes how to store the generated peering + token. + properties: + backend: + description: 'Backend is where the generated secret is stored. + Currently supports the value: "kubernetes".' + type: string + key: + description: Key is the key of the secret generated. + type: string + name: + description: Name is the name of the secret generated. + type: string + type: object + type: object + required: + - peer + type: object + status: + description: PeeringAcceptorStatus defines the observed state of PeeringAcceptor. + properties: + conditions: + description: Conditions indicate the latest available observations + of a resource's current state. + items: + description: |- + Conditions define a readiness condition for a Consul resource. + See: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties + properties: + lastTransitionTime: + description: LastTransitionTime is the 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 condition. + type: string + required: + - status + - type + type: object + type: array + lastSyncedTime: + description: LastSyncedTime is the last time the resource successfully + synced with Consul. + format: date-time + type: string + latestPeeringVersion: + description: LatestPeeringVersion is the latest version of the resource + that was reconciled. + format: int64 + type: integer + secret: + description: SecretRef shows the status of the secret. + properties: + backend: + description: 'Backend is where the generated secret is stored. + Currently supports the value: "kubernetes".' + type: string + key: + description: Key is the key of the secret generated. + type: string + name: + description: Name is the name of the secret generated. + type: string + resourceVersion: + description: ResourceVersion is the resource version for the secret. + type: string + type: object + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- end }} diff --git a/kubernetes-vault/consul/templates/crd-peeringdialers.yaml b/kubernetes-vault/consul/templates/crd-peeringdialers.yaml new file mode 100644 index 0000000..562c760 --- /dev/null +++ b/kubernetes-vault/consul/templates/crd-peeringdialers.yaml @@ -0,0 +1,152 @@ +{{- if and .Values.connectInject.enabled .Values.global.peering.enabled }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: crd + name: peeringdialers.consul.hashicorp.com +spec: + group: consul.hashicorp.com + names: + kind: PeeringDialer + listKind: PeeringDialerList + plural: peeringdialers + shortNames: + - peering-dialer + singular: peeringdialer + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The sync status of the resource with Consul + jsonPath: .status.conditions[?(@.type=="Synced")].status + name: Synced + type: string + - description: The last successful synced time of the resource with Consul + jsonPath: .status.lastSyncedTime + name: Last Synced + type: date + - description: The age of the resource + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: PeeringDialer is the Schema for the peeringdialers 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: PeeringDialerSpec defines the desired state of PeeringDialer. + properties: + peer: + description: Peer describes the information needed to create a peering. + properties: + secret: + description: Secret describes how to store the generated peering + token. + properties: + backend: + description: 'Backend is where the generated secret is stored. + Currently supports the value: "kubernetes".' + type: string + key: + description: Key is the key of the secret generated. + type: string + name: + description: Name is the name of the secret generated. + type: string + type: object + type: object + required: + - peer + type: object + status: + description: PeeringDialerStatus defines the observed state of PeeringDialer. + properties: + conditions: + description: Conditions indicate the latest available observations + of a resource's current state. + items: + description: |- + Conditions define a readiness condition for a Consul resource. + See: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties + properties: + lastTransitionTime: + description: LastTransitionTime is the 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 condition. + type: string + required: + - status + - type + type: object + type: array + lastSyncedTime: + description: LastSyncedTime is the last time the resource successfully + synced with Consul. + format: date-time + type: string + latestPeeringVersion: + description: LatestPeeringVersion is the latest version of the resource + that was reconciled. + format: int64 + type: integer + secret: + description: SecretRef shows the status of the secret. + properties: + backend: + description: 'Backend is where the generated secret is stored. + Currently supports the value: "kubernetes".' + type: string + key: + description: Key is the key of the secret generated. + type: string + name: + description: Name is the name of the secret generated. + type: string + resourceVersion: + description: ResourceVersion is the resource version for the secret. + type: string + type: object + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- end }} diff --git a/kubernetes-vault/consul/templates/crd-proxyconfigurations.yaml b/kubernetes-vault/consul/templates/crd-proxyconfigurations.yaml new file mode 100644 index 0000000..464fdfe --- /dev/null +++ b/kubernetes-vault/consul/templates/crd-proxyconfigurations.yaml @@ -0,0 +1,426 @@ +{{- if .Values.connectInject.enabled }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: crd + name: proxyconfigurations.mesh.consul.hashicorp.com +spec: + group: mesh.consul.hashicorp.com + names: + kind: ProxyConfiguration + listKind: ProxyConfigurationList + plural: proxyconfigurations + shortNames: + - proxy-configuration + singular: proxyconfiguration + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The sync status of the resource with Consul + jsonPath: .status.conditions[?(@.type=="Synced")].status + name: Synced + type: string + - description: The last successful synced time of the resource with Consul + jsonPath: .status.lastSyncedTime + name: Last Synced + type: date + - description: The age of the resource + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v2beta1 + schema: + openAPIV3Schema: + description: ProxyConfiguration is the Schema for the TCP Routes 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: This is a Resource type. + properties: + bootstrapConfig: + description: |- + bootstrap_config is the configuration that requires proxies + to be restarted to be applied. + properties: + dogstatsdUrl: + type: string + overrideJsonTpl: + type: string + prometheusBindAddr: + type: string + readyBindAddr: + type: string + staticClustersJson: + type: string + staticListenersJson: + type: string + statsBindAddr: + type: string + statsConfigJson: + type: string + statsFlushInterval: + type: string + statsSinksJson: + type: string + statsTags: + items: + type: string + type: array + statsdUrl: + type: string + telemetryCollectorBindSocketDir: + type: string + tracingConfigJson: + type: string + type: object + dynamicConfig: + description: |- + dynamic_config is the configuration that could be changed + dynamically (i.e. without needing restart). + properties: + accessLogs: + description: AccessLogs configures the output and format of Envoy + access logs + properties: + disableListenerLogs: + description: |- + DisableListenerLogs turns off just listener logs for connections rejected by Envoy because they don't + have a matching listener filter. + type: boolean + enabled: + description: Enabled turns off all access logging + type: boolean + jsonFormat: + description: |- + The presence of one format string or the other implies the access log string encoding. + Defining both is invalid. + type: string + path: + description: Path is the output file to write logs + type: string + textFormat: + type: string + type: + description: 'Type selects the output for logs: "file", "stderr". + "stdout"' + enum: + - LOG_SINK_TYPE_DEFAULT + - LOG_SINK_TYPE_FILE + - LOG_SINK_TYPE_STDERR + - LOG_SINK_TYPE_STDOUT + format: int32 + type: string + type: object + exposeConfig: + properties: + exposePaths: + items: + properties: + listenerPort: + format: int32 + type: integer + localPathPort: + format: int32 + type: integer + path: + type: string + protocol: + enum: + - EXPOSE_PATH_PROTOCOL_HTTP + - EXPOSE_PATH_PROTOCOL_HTTP2 + format: int32 + type: string + type: object + type: array + type: object + inboundConnections: + description: inbound_connections configures inbound connections + to the proxy. + properties: + balanceInboundConnections: + enum: + - BALANCE_CONNECTIONS_DEFAULT + - BALANCE_CONNECTIONS_EXACT + format: int32 + type: string + maxInboundConnections: + format: int32 + type: integer + type: object + listenerTracingJson: + type: string + localClusterJson: + type: string + localConnection: + additionalProperties: + description: Referenced by ProxyConfiguration + properties: + connectTimeout: + description: "A Duration represents a signed, fixed-length + span of time represented\nas a count of seconds and fractions + of seconds at nanosecond\nresolution. It is independent + of any calendar and concepts like \"day\"\nor \"month\". + It is related to Timestamp in that the difference between\ntwo + Timestamp values is a Duration and it can be added or + subtracted\nfrom a Timestamp. Range is approximately +-10,000 + years.\n\n\n# Examples\n\n\nExample 1: Compute Duration + from two Timestamps in pseudo code.\n\n\n\tTimestamp start + = ...;\n\tTimestamp end = ...;\n\tDuration duration = + ...;\n\n\n\tduration.seconds = end.seconds - start.seconds;\n\tduration.nanos + = end.nanos - start.nanos;\n\n\n\tif (duration.seconds + < 0 && duration.nanos > 0) {\n\t duration.seconds += + 1;\n\t duration.nanos -= 1000000000;\n\t} else if (duration.seconds + > 0 && duration.nanos < 0) {\n\t duration.seconds -= + 1;\n\t duration.nanos += 1000000000;\n\t}\n\n\nExample + 2: Compute Timestamp from Timestamp + Duration in pseudo + code.\n\n\n\tTimestamp start = ...;\n\tDuration duration + = ...;\n\tTimestamp end = ...;\n\n\n\tend.seconds = start.seconds + + duration.seconds;\n\tend.nanos = start.nanos + duration.nanos;\n\n\n\tif + (end.nanos < 0) {\n\t end.seconds -= 1;\n\t end.nanos + += 1000000000;\n\t} else if (end.nanos >= 1000000000) + {\n\t end.seconds += 1;\n\t end.nanos -= 1000000000;\n\t}\n\n\nExample + 3: Compute Duration from datetime.timedelta in Python.\n\n\n\ttd + = datetime.timedelta(days=3, minutes=10)\n\tduration = + Duration()\n\tduration.FromTimedelta(td)\n\n\n# JSON Mapping\n\n\nIn + JSON format, the Duration type is encoded as a string + rather than an\nobject, where the string ends in the suffix + \"s\" (indicating seconds) and\nis preceded by the number + of seconds, with nanoseconds expressed as\nfractional + seconds. For example, 3 seconds with 0 nanoseconds should + be\nencoded in JSON format as \"3s\", while 3 seconds + and 1 nanosecond should\nbe expressed in JSON format as + \"3.000000001s\", and 3 seconds and 1\nmicrosecond should + be expressed in JSON format as \"3.000001s\"." + format: duration + properties: + nanos: + description: |- + Signed fractions of a second at nanosecond resolution of the span + of time. Durations less than one second are represented with a 0 + `seconds` field and a positive or negative `nanos` field. For durations + of one second or more, a non-zero value for the `nanos` field must be + of the same sign as the `seconds` field. Must be from -999,999,999 + to +999,999,999 inclusive. + format: int32 + type: integer + seconds: + description: |- + Signed seconds of the span of time. Must be from -315,576,000,000 + to +315,576,000,000 inclusive. Note: these bounds are computed from: + 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years + format: int64 + type: integer + type: object + requestTimeout: + description: "A Duration represents a signed, fixed-length + span of time represented\nas a count of seconds and fractions + of seconds at nanosecond\nresolution. It is independent + of any calendar and concepts like \"day\"\nor \"month\". + It is related to Timestamp in that the difference between\ntwo + Timestamp values is a Duration and it can be added or + subtracted\nfrom a Timestamp. Range is approximately +-10,000 + years.\n\n\n# Examples\n\n\nExample 1: Compute Duration + from two Timestamps in pseudo code.\n\n\n\tTimestamp start + = ...;\n\tTimestamp end = ...;\n\tDuration duration = + ...;\n\n\n\tduration.seconds = end.seconds - start.seconds;\n\tduration.nanos + = end.nanos - start.nanos;\n\n\n\tif (duration.seconds + < 0 && duration.nanos > 0) {\n\t duration.seconds += + 1;\n\t duration.nanos -= 1000000000;\n\t} else if (duration.seconds + > 0 && duration.nanos < 0) {\n\t duration.seconds -= + 1;\n\t duration.nanos += 1000000000;\n\t}\n\n\nExample + 2: Compute Timestamp from Timestamp + Duration in pseudo + code.\n\n\n\tTimestamp start = ...;\n\tDuration duration + = ...;\n\tTimestamp end = ...;\n\n\n\tend.seconds = start.seconds + + duration.seconds;\n\tend.nanos = start.nanos + duration.nanos;\n\n\n\tif + (end.nanos < 0) {\n\t end.seconds -= 1;\n\t end.nanos + += 1000000000;\n\t} else if (end.nanos >= 1000000000) + {\n\t end.seconds += 1;\n\t end.nanos -= 1000000000;\n\t}\n\n\nExample + 3: Compute Duration from datetime.timedelta in Python.\n\n\n\ttd + = datetime.timedelta(days=3, minutes=10)\n\tduration = + Duration()\n\tduration.FromTimedelta(td)\n\n\n# JSON Mapping\n\n\nIn + JSON format, the Duration type is encoded as a string + rather than an\nobject, where the string ends in the suffix + \"s\" (indicating seconds) and\nis preceded by the number + of seconds, with nanoseconds expressed as\nfractional + seconds. For example, 3 seconds with 0 nanoseconds should + be\nencoded in JSON format as \"3s\", while 3 seconds + and 1 nanosecond should\nbe expressed in JSON format as + \"3.000000001s\", and 3 seconds and 1\nmicrosecond should + be expressed in JSON format as \"3.000001s\"." + format: duration + properties: + nanos: + description: |- + Signed fractions of a second at nanosecond resolution of the span + of time. Durations less than one second are represented with a 0 + `seconds` field and a positive or negative `nanos` field. For durations + of one second or more, a non-zero value for the `nanos` field must be + of the same sign as the `seconds` field. Must be from -999,999,999 + to +999,999,999 inclusive. + format: int32 + type: integer + seconds: + description: |- + Signed seconds of the span of time. Must be from -315,576,000,000 + to +315,576,000,000 inclusive. Note: these bounds are computed from: + 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years + format: int64 + type: integer + type: object + type: object + description: |- + local_connection is the configuration that should be used + to connect to the local application provided per-port. + The map keys should correspond to port names on the workload. + type: object + localWorkloadAddress: + description: |- + deprecated: + local_workload_address, local_workload_port, and local_workload_socket_path + are deprecated and are only needed for migration of existing resources. + + + Deprecated: Marked as deprecated in pbmesh/v2beta1/proxy_configuration.proto. + type: string + localWorkloadPort: + description: 'Deprecated: Marked as deprecated in pbmesh/v2beta1/proxy_configuration.proto.' + format: int32 + type: integer + localWorkloadSocketPath: + description: 'Deprecated: Marked as deprecated in pbmesh/v2beta1/proxy_configuration.proto.' + type: string + meshGatewayMode: + enum: + - MESH_GATEWAY_MODE_UNSPECIFIED + - MESH_GATEWAY_MODE_NONE + - MESH_GATEWAY_MODE_LOCAL + - MESH_GATEWAY_MODE_REMOTE + format: int32 + type: string + mode: + description: mode indicates the proxy's mode. This will default + to 'transparent'. + enum: + - PROXY_MODE_DEFAULT + - PROXY_MODE_TRANSPARENT + - PROXY_MODE_DIRECT + format: int32 + type: string + mutualTlsMode: + enum: + - MUTUAL_TLS_MODE_DEFAULT + - MUTUAL_TLS_MODE_STRICT + - MUTUAL_TLS_MODE_PERMISSIVE + format: int32 + type: string + publicListenerJson: + type: string + transparentProxy: + properties: + dialedDirectly: + description: |- + dialed_directly indicates whether this proxy should be dialed using original destination IP + in the connection rather than load balance between all endpoints. + type: boolean + outboundListenerPort: + description: |- + outbound_listener_port is the port for the proxy's outbound listener. + This defaults to 15001. + format: int32 + type: integer + type: object + type: object + opaqueConfig: + description: |- + deprecated: prevent usage when using v2 APIs directly. + needed for backwards compatibility + + + Deprecated: Marked as deprecated in pbmesh/v2beta1/proxy_configuration.proto. + type: object + x-kubernetes-preserve-unknown-fields: true + workloads: + description: |- + Selection of workloads this proxy configuration should apply to. + These can be prefixes or specific workload names. + properties: + filter: + type: string + names: + items: + type: string + type: array + prefixes: + items: + type: string + type: array + type: object + type: object + status: + properties: + conditions: + description: Conditions indicate the latest available observations + of a resource's current state. + items: + description: |- + Conditions define a readiness condition for a Consul resource. + See: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties + properties: + lastTransitionTime: + description: LastTransitionTime is the 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 condition. + type: string + required: + - status + - type + type: object + type: array + lastSyncedTime: + description: LastSyncedTime is the last time the resource successfully + synced with Consul. + format: date-time + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- end }} diff --git a/kubernetes-vault/consul/templates/crd-proxydefaults.yaml b/kubernetes-vault/consul/templates/crd-proxydefaults.yaml new file mode 100644 index 0000000..a5fa817 --- /dev/null +++ b/kubernetes-vault/consul/templates/crd-proxydefaults.yaml @@ -0,0 +1,278 @@ +{{- if .Values.connectInject.enabled }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: crd + name: proxydefaults.consul.hashicorp.com +spec: + group: consul.hashicorp.com + names: + kind: ProxyDefaults + listKind: ProxyDefaultsList + plural: proxydefaults + shortNames: + - proxy-defaults + singular: proxydefaults + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The sync status of the resource with Consul + jsonPath: .status.conditions[?(@.type=="Synced")].status + name: Synced + type: string + - description: The last successful synced time of the resource with Consul + jsonPath: .status.lastSyncedTime + name: Last Synced + type: date + - description: The age of the resource + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: ProxyDefaults is the Schema for the proxydefaults 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: ProxyDefaultsSpec defines the desired state of ProxyDefaults. + properties: + accessLogs: + description: AccessLogs controls all envoy instances' access logging + configuration. + properties: + disableListenerLogs: + description: |- + DisableListenerLogs turns off just listener logs for connections rejected by Envoy because they don't + have a matching listener filter. + type: boolean + enabled: + description: Enabled turns on all access logging + type: boolean + jsonFormat: + description: |- + JSONFormat is a JSON-formatted string of an Envoy access log format dictionary. + See for more info on formatting: https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#format-dictionaries + Defining JSONFormat and TextFormat is invalid. + type: string + path: + description: Path is the output file to write logs for file-type + logging + type: string + textFormat: + description: |- + TextFormat is a representation of Envoy access logs format. + See for more info on formatting: https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#format-strings + Defining JSONFormat and TextFormat is invalid. + type: string + type: + description: |- + Type selects the output for logs + one of "file", "stderr". "stdout" + type: string + type: object + config: + description: |- + Config is an arbitrary map of configuration values used by Connect proxies. + Any values that your proxy allows can be configured globally here. + Supports JSON config values. See https://www.consul.io/docs/connect/proxies/envoy#configuration-formatting + type: object + x-kubernetes-preserve-unknown-fields: true + envoyExtensions: + description: EnvoyExtensions are a list of extensions to modify Envoy + proxy configuration. + items: + description: EnvoyExtension has configuration for an extension that + patches Envoy resources. + properties: + arguments: + type: object + x-kubernetes-preserve-unknown-fields: true + name: + type: string + required: + type: boolean + type: object + type: array + expose: + description: Expose controls the default expose path configuration + for Envoy. + properties: + checks: + description: |- + Checks defines whether paths associated with Consul checks will be exposed. + This flag triggers exposing all HTTP and GRPC check paths registered for the service. + type: boolean + paths: + description: Paths is the list of paths exposed through the proxy. + items: + properties: + listenerPort: + description: ListenerPort defines the port of the proxy's + listener for exposed paths. + type: integer + localPathPort: + description: LocalPathPort is the port that the service + is listening on for the given path. + type: integer + path: + description: Path is the path to expose through the proxy, + ie. "/metrics". + type: string + protocol: + description: |- + Protocol describes the upstream's service protocol. + Valid values are "http" and "http2", defaults to "http". + type: string + type: object + type: array + type: object + failoverPolicy: + description: FailoverPolicy specifies the exact mechanism used for + failover. + properties: + mode: + description: |- + Mode specifies the type of failover that will be performed. Valid values are + "sequential", "" (equivalent to "sequential") and "order-by-locality". + type: string + regions: + description: |- + Regions is the ordered list of the regions of the failover targets. + Valid values can be "us-west-1", "us-west-2", and so on. + items: + type: string + type: array + type: object + meshGateway: + description: MeshGateway controls the default mesh gateway configuration + for this service. + properties: + mode: + description: |- + Mode is the mode that should be used for the upstream connection. + One of none, local, or remote. + type: string + type: object + mode: + description: |- + Mode can be one of "direct" or "transparent". "transparent" represents that inbound and outbound + application traffic is being captured and redirected through the proxy. This mode does not + enable the traffic redirection itself. Instead it signals Consul to configure Envoy as if + traffic is already being redirected. "direct" represents that the proxy's listeners must be + dialed directly by the local application and other proxies. + Note: This cannot be set using the CRD and should be set using annotations on the + services that are part of the mesh. + type: string + mutualTLSMode: + description: |- + MutualTLSMode controls whether mutual TLS is required for all incoming + connections when transparent proxy is enabled. This can be set to + "permissive" or "strict". "strict" is the default which requires mutual + TLS for incoming connections. In the insecure "permissive" mode, + connections to the sidecar proxy public listener port require mutual + TLS, but connections to the service port do not require mutual TLS and + are proxied to the application unmodified. Note: Intentions are not + enforced for non-mTLS connections. To keep your services secure, we + recommend using "strict" mode whenever possible and enabling + "permissive" mode only when necessary. + type: string + prioritizeByLocality: + description: |- + PrioritizeByLocality controls whether the locality of services within the + local partition will be used to prioritize connectivity. + properties: + mode: + description: |- + Mode specifies the type of prioritization that will be performed + when selecting nodes in the local partition. + Valid values are: "" (default "none"), "none", and "failover". + type: string + type: object + transparentProxy: + description: |- + TransparentProxy controls configuration specific to proxies in transparent mode. + Note: This cannot be set using the CRD and should be set using annotations on the + services that are part of the mesh. + properties: + dialedDirectly: + description: |- + DialedDirectly indicates whether transparent proxies can dial this proxy instance directly. + The discovery chain is not considered when dialing a service instance directly. + This setting is useful when addressing stateful services, such as a database cluster with a leader node. + type: boolean + outboundListenerPort: + description: |- + OutboundListenerPort is the port of the listener where outbound application + traffic is being redirected to. + type: integer + type: object + type: object + status: + properties: + conditions: + description: Conditions indicate the latest available observations + of a resource's current state. + items: + description: |- + Conditions define a readiness condition for a Consul resource. + See: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties + properties: + lastTransitionTime: + description: LastTransitionTime is the 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 condition. + type: string + required: + - status + - type + type: object + type: array + lastSyncedTime: + description: LastSyncedTime is the last time the resource successfully + synced with Consul. + format: date-time + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- end }} diff --git a/kubernetes-vault/consul/templates/crd-referencegrants-external.yaml b/kubernetes-vault/consul/templates/crd-referencegrants-external.yaml new file mode 100644 index 0000000..db9cf12 --- /dev/null +++ b/kubernetes-vault/consul/templates/crd-referencegrants-external.yaml @@ -0,0 +1,208 @@ +{{- if and .Values.connectInject.enabled .Values.connectInject.apiGateway.manageExternalCRDs }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/1538 + gateway.networking.k8s.io/bundle-version: v0.6.2 + gateway.networking.k8s.io/channel: experimental + creationTimestamp: null + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: crd + name: referencegrants.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: ReferenceGrant + listKind: ReferenceGrantList + plural: referencegrants + shortNames: + - refgrant + singular: referencegrant + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha2 + schema: + openAPIV3Schema: + description: "ReferenceGrant identifies kinds of resources in other namespaces that are trusted to reference the specified kinds of resources in the same namespace as the policy. \n Each ReferenceGrant can be used to represent a unique trust relationship. Additional Reference Grants can be used to add to the set of trusted sources of inbound references for the namespace they are defined within. \n All cross-namespace references in Gateway API (with the exception of cross-namespace Gateway-route attachment) require a ReferenceGrant. \n ReferenceGrant is a form of runtime verification allowing users to assert which cross-namespace object references are permitted. Implementations that support ReferenceGrant MUST NOT permit cross-namespace references which have no grant, and MUST respond to the removal of a grant by revoking the access that the grant allowed. \n Support: Core" + 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 ReferenceGrant. + properties: + from: + description: "From describes the trusted namespaces and kinds that can reference the resources described in \"To\". Each entry in this list MUST be considered to be an additional place that references can be valid from, or to put this another way, entries MUST be combined using OR. \n Support: Core" + items: + description: ReferenceGrantFrom describes trusted namespaces and kinds. + properties: + group: + description: "Group is the group of the referent. When empty, the Kubernetes core API group is inferred. \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: + description: "Kind is the kind of the referent. Although implementations may support additional resources, the following types are part of the \"Core\" support level for this field. \n When used to permit a SecretObjectReference: \n * Gateway \n When used to permit a BackendObjectReference: \n * GRPCRoute * HTTPRoute * TCPRoute * TLSRoute * UDPRoute" + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + namespace: + description: "Namespace is the namespace of the referent. \n Support: Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - group + - kind + - namespace + type: object + maxItems: 16 + minItems: 1 + type: array + to: + description: "To describes the resources that may be referenced by the resources described in \"From\". Each entry in this list MUST be considered to be an additional place that references can be valid to, or to put this another way, entries MUST be combined using OR. \n Support: Core" + items: + description: ReferenceGrantTo describes what Kinds are allowed as targets of the references. + properties: + group: + description: "Group is the group of the referent. When empty, the Kubernetes core API group is inferred. \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: + description: "Kind is the kind of the referent. Although implementations may support additional resources, the following types are part of the \"Core\" support level for this field: \n * Secret when used to permit a SecretObjectReference * Service when used to permit a BackendObjectReference" + 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 policy refers to all resources of the specified Group and Kind in the local namespace. + maxLength: 253 + minLength: 1 + type: string + required: + - group + - kind + type: object + maxItems: 16 + minItems: 1 + type: array + required: + - from + - to + type: object + type: object + served: true + storage: true + subresources: {} + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: "ReferenceGrant identifies kinds of resources in other namespaces that are trusted to reference the specified kinds of resources in the same namespace as the policy. \n Each ReferenceGrant can be used to represent a unique trust relationship. Additional Reference Grants can be used to add to the set of trusted sources of inbound references for the namespace they are defined within. \n All cross-namespace references in Gateway API (with the exception of cross-namespace Gateway-route attachment) require a ReferenceGrant. \n ReferenceGrant is a form of runtime verification allowing users to assert which cross-namespace object references are permitted. Implementations that support ReferenceGrant MUST NOT permit cross-namespace references which have no grant, and MUST respond to the removal of a grant by revoking the access that the grant allowed. \n Support: Core" + 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 ReferenceGrant. + properties: + from: + description: "From describes the trusted namespaces and kinds that can reference the resources described in \"To\". Each entry in this list MUST be considered to be an additional place that references can be valid from, or to put this another way, entries MUST be combined using OR. \n Support: Core" + items: + description: ReferenceGrantFrom describes trusted namespaces and kinds. + properties: + group: + description: "Group is the group of the referent. When empty, the Kubernetes core API group is inferred. \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: + description: "Kind is the kind of the referent. Although implementations may support additional resources, the following types are part of the \"Core\" support level for this field. \n When used to permit a SecretObjectReference: \n * Gateway \n When used to permit a BackendObjectReference: \n * GRPCRoute * HTTPRoute * TCPRoute * TLSRoute * UDPRoute" + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + namespace: + description: "Namespace is the namespace of the referent. \n Support: Core" + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - group + - kind + - namespace + type: object + maxItems: 16 + minItems: 1 + type: array + to: + description: "To describes the resources that may be referenced by the resources described in \"From\". Each entry in this list MUST be considered to be an additional place that references can be valid to, or to put this another way, entries MUST be combined using OR. \n Support: Core" + items: + description: ReferenceGrantTo describes what Kinds are allowed as targets of the references. + properties: + group: + description: "Group is the group of the referent. When empty, the Kubernetes core API group is inferred. \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: + description: "Kind is the kind of the referent. Although implementations may support additional resources, the following types are part of the \"Core\" support level for this field: \n * Secret when used to permit a SecretObjectReference * Service when used to permit a BackendObjectReference" + 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 policy refers to all resources of the specified Group and Kind in the local namespace. + maxLength: 253 + minLength: 1 + type: string + required: + - group + - kind + type: object + maxItems: 16 + minItems: 1 + type: array + required: + - from + - to + type: object + type: object + served: true + storage: false + subresources: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +{{- end }} diff --git a/kubernetes-vault/consul/templates/crd-registrations.yaml b/kubernetes-vault/consul/templates/crd-registrations.yaml new file mode 100644 index 0000000..f126978 --- /dev/null +++ b/kubernetes-vault/consul/templates/crd-registrations.yaml @@ -0,0 +1,257 @@ +{{- if .Values.connectInject.enabled }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: crd + name: registrations.consul.hashicorp.com +spec: + group: consul.hashicorp.com + names: + kind: Registration + listKind: RegistrationList + plural: registrations + singular: registration + scope: Cluster + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: Registration defines the resource for working with service registrations. + 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 Registration. + properties: + address: + type: string + check: + description: HealthCheck is used to represent a single check. + properties: + checkId: + type: string + definition: + description: |- + HealthCheckDefinition is used to store the details about + a health check's execution. + properties: + body: + type: string + deregisterCriticalServiceAfterDuration: + type: string + grpc: + type: string + grpcUseTLS: + type: boolean + header: + additionalProperties: + items: + type: string + type: array + type: object + http: + type: string + intervalDuration: + type: string + method: + type: string + osService: + type: string + tcp: + type: string + tcpUseTLS: + type: boolean + timeoutDuration: + type: string + tlsServerName: + type: string + tlsSkipVerify: + type: boolean + udp: + type: string + required: + - intervalDuration + type: object + exposedPort: + type: integer + name: + type: string + namespace: + type: string + node: + type: string + notes: + type: string + output: + type: string + partition: + type: string + serviceId: + type: string + serviceName: + type: string + status: + type: string + type: + type: string + required: + - checkId + - definition + - name + - serviceId + - serviceName + - status + type: object + datacenter: + type: string + id: + type: string + locality: + properties: + region: + type: string + zone: + type: string + type: object + node: + type: string + nodeMeta: + additionalProperties: + type: string + type: object + partition: + type: string + service: + properties: + address: + type: string + enableTagOverride: + type: boolean + id: + type: string + locality: + properties: + region: + type: string + zone: + type: string + type: object + meta: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + partition: + type: string + port: + type: integer + socketPath: + type: string + taggedAddresses: + additionalProperties: + properties: + address: + type: string + port: + type: integer + required: + - address + - port + type: object + type: object + tags: + items: + type: string + type: array + weights: + properties: + passing: + type: integer + warning: + type: integer + required: + - passing + - warning + type: object + required: + - name + - port + type: object + skipNodeUpdate: + type: boolean + taggedAddresses: + additionalProperties: + type: string + type: object + type: object + status: + description: RegistrationStatus defines the observed state of Registration. + properties: + conditions: + description: Conditions indicate the latest available observations + of a resource's current state. + items: + description: |- + Conditions define a readiness condition for a Consul resource. + See: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties + properties: + lastTransitionTime: + description: LastTransitionTime is the 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 condition. + type: string + required: + - status + - type + type: object + type: array + lastSyncedTime: + description: LastSyncedTime is the last time the resource successfully + synced with Consul. + format: date-time + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- end }} diff --git a/kubernetes-vault/consul/templates/crd-routeauthfilters.yaml b/kubernetes-vault/consul/templates/crd-routeauthfilters.yaml new file mode 100644 index 0000000..65403e6 --- /dev/null +++ b/kubernetes-vault/consul/templates/crd-routeauthfilters.yaml @@ -0,0 +1,215 @@ +{{- if .Values.connectInject.enabled }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: crd + name: routeauthfilters.consul.hashicorp.com +spec: + group: consul.hashicorp.com + names: + kind: RouteAuthFilter + listKind: RouteAuthFilterList + plural: routeauthfilters + singular: routeauthfilter + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The sync status of the resource with Consul + jsonPath: .status.conditions[?(@.type=="Synced")].status + name: Synced + type: string + - description: The last successful synced time of the resource with Consul + jsonPath: .status.lastSyncedTime + name: Last Synced + type: date + - description: The age of the resource + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: RouteAuthFilter is the Schema for the routeauthfilters 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: RouteAuthFilterSpec defines the desired state of RouteAuthFilter. + properties: + jwt: + description: This re-uses the JWT requirement type from Gateway Policy + Types. + properties: + providers: + description: Providers is a list of providers to consider when + verifying a JWT. + items: + description: GatewayJWTProvider holds the provider and claim + verification information. + properties: + name: + description: |- + Name is the name of the JWT provider. There MUST be a corresponding + "jwt-provider" config entry with this name. + type: string + verifyClaims: + description: VerifyClaims is a list of additional claims + to verify in a JWT's payload. + items: + description: GatewayJWTClaimVerification holds the actual + claim information to be verified. + properties: + path: + description: Path is the path to the claim in the + token JSON. + items: + type: string + type: array + value: + description: |- + Value is the expected value at the given path: + - If the type at the path is a list then we verify + that this value is contained in the list. + + + - If the type at the path is a string then we verify + that this value matches. + type: string + required: + - path + - value + type: object + type: array + required: + - name + type: object + type: array + required: + - providers + type: object + type: object + status: + description: RouteAuthFilterStatus defines the observed state of the gateway. + properties: + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Accepted + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: ResolvedRefs + description: |- + Conditions describe the current conditions of the Filter. + + + Known condition types are: + + + * "Accepted" + * "ResolvedRefs" + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + 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: {} +{{- end }} diff --git a/kubernetes-vault/consul/templates/crd-routeretryfilters.yaml b/kubernetes-vault/consul/templates/crd-routeretryfilters.yaml new file mode 100644 index 0000000..d26dff9 --- /dev/null +++ b/kubernetes-vault/consul/templates/crd-routeretryfilters.yaml @@ -0,0 +1,121 @@ +{{- if .Values.connectInject.enabled }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: crd + name: routeretryfilters.consul.hashicorp.com +spec: + group: consul.hashicorp.com + names: + kind: RouteRetryFilter + listKind: RouteRetryFilterList + plural: routeretryfilters + singular: routeretryfilter + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The sync status of the resource with Consul + jsonPath: .status.conditions[?(@.type=="Synced")].status + name: Synced + type: string + - description: The last successful synced time of the resource with Consul + jsonPath: .status.lastSyncedTime + name: Last Synced + type: date + - description: The age of the resource + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: RouteRetryFilter is the Schema for the routeretryfilters 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: RouteRetryFilterSpec defines the desired state of RouteRetryFilter. + properties: + numRetries: + format: int32 + minimum: 0 + type: integer + retryOn: + items: + type: string + type: array + retryOnConnectFailure: + type: boolean + retryOnStatusCodes: + items: + format: int32 + type: integer + type: array + type: object + status: + properties: + conditions: + description: Conditions indicate the latest available observations + of a resource's current state. + items: + description: |- + Conditions define a readiness condition for a Consul resource. + See: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties + properties: + lastTransitionTime: + description: LastTransitionTime is the 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 condition. + type: string + required: + - status + - type + type: object + type: array + lastSyncedTime: + description: LastSyncedTime is the last time the resource successfully + synced with Consul. + format: date-time + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- end }} diff --git a/kubernetes-vault/consul/templates/crd-routetimeoutfilters.yaml b/kubernetes-vault/consul/templates/crd-routetimeoutfilters.yaml new file mode 100644 index 0000000..568b025 --- /dev/null +++ b/kubernetes-vault/consul/templates/crd-routetimeoutfilters.yaml @@ -0,0 +1,113 @@ +{{- if .Values.connectInject.enabled }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: crd + name: routetimeoutfilters.consul.hashicorp.com +spec: + group: consul.hashicorp.com + names: + kind: RouteTimeoutFilter + listKind: RouteTimeoutFilterList + plural: routetimeoutfilters + singular: routetimeoutfilter + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The sync status of the resource with Consul + jsonPath: .status.conditions[?(@.type=="Synced")].status + name: Synced + type: string + - description: The last successful synced time of the resource with Consul + jsonPath: .status.lastSyncedTime + name: Last Synced + type: date + - description: The age of the resource + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: RouteTimeoutFilter is the Schema for the httproutetimeoutfilters + 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: RouteTimeoutFilterSpec defines the desired state of RouteTimeoutFilter. + properties: + idleTimeout: + format: duration + type: string + requestTimeout: + format: duration + type: string + type: object + status: + properties: + conditions: + description: Conditions indicate the latest available observations + of a resource's current state. + items: + description: |- + Conditions define a readiness condition for a Consul resource. + See: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties + properties: + lastTransitionTime: + description: LastTransitionTime is the 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 condition. + type: string + required: + - status + - type + type: object + type: array + lastSyncedTime: + description: LastSyncedTime is the last time the resource successfully + synced with Consul. + format: date-time + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- end }} diff --git a/kubernetes-vault/consul/templates/crd-samenessgroups.yaml b/kubernetes-vault/consul/templates/crd-samenessgroups.yaml new file mode 100644 index 0000000..29cd24f --- /dev/null +++ b/kubernetes-vault/consul/templates/crd-samenessgroups.yaml @@ -0,0 +1,133 @@ +{{- if .Values.connectInject.enabled }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: crd + name: samenessgroups.consul.hashicorp.com +spec: + group: consul.hashicorp.com + names: + kind: SamenessGroup + listKind: SamenessGroupList + plural: samenessgroups + shortNames: + - sameness-group + singular: samenessgroup + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The sync status of the resource with Consul + jsonPath: .status.conditions[?(@.type=="Synced")].status + name: Synced + type: string + - description: The last successful synced time of the resource with Consul + jsonPath: .status.lastSyncedTime + name: Last Synced + type: date + - description: The age of the resource + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: SamenessGroup is the Schema for the samenessgroups 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: SamenessGroupSpec defines the desired state of SamenessGroup. + properties: + defaultForFailover: + description: |- + DefaultForFailover indicates that upstream requests to members of the given sameness group will implicitly failover between members of this sameness group. + When DefaultForFailover is true, the local partition must be a member of the sameness group or IncludeLocal must be set to true. + type: boolean + includeLocal: + description: |- + IncludeLocal is used to include the local partition as the first member of the sameness group. + The local partition can only be a member of a single sameness group. + type: boolean + members: + description: |- + Members are the partitions and peers that are part of the sameness group. + If a member of a sameness group does not exist, it will be ignored. + items: + properties: + partition: + description: |- + The partitions and peers that are part of the sameness group. + A sameness group member cannot define both peer and partition at the same time. + type: string + peer: + type: string + type: object + type: array + type: object + status: + properties: + conditions: + description: Conditions indicate the latest available observations + of a resource's current state. + items: + description: |- + Conditions define a readiness condition for a Consul resource. + See: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties + properties: + lastTransitionTime: + description: LastTransitionTime is the 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 condition. + type: string + required: + - status + - type + type: object + type: array + lastSyncedTime: + description: LastSyncedTime is the last time the resource successfully + synced with Consul. + format: date-time + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- end }} diff --git a/kubernetes-vault/consul/templates/crd-servicedefaults.yaml b/kubernetes-vault/consul/templates/crd-servicedefaults.yaml new file mode 100644 index 0000000..a976d09 --- /dev/null +++ b/kubernetes-vault/consul/templates/crd-servicedefaults.yaml @@ -0,0 +1,580 @@ +{{- if .Values.connectInject.enabled }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: crd + name: servicedefaults.consul.hashicorp.com +spec: + group: consul.hashicorp.com + names: + kind: ServiceDefaults + listKind: ServiceDefaultsList + plural: servicedefaults + shortNames: + - service-defaults + singular: servicedefaults + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The sync status of the resource with Consul + jsonPath: .status.conditions[?(@.type=="Synced")].status + name: Synced + type: string + - description: The last successful synced time of the resource with Consul + jsonPath: .status.lastSyncedTime + name: Last Synced + type: date + - description: The age of the resource + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: ServiceDefaults is the Schema for the servicedefaults 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: ServiceDefaultsSpec defines the desired state of ServiceDefaults. + properties: + balanceInboundConnections: + description: |- + BalanceInboundConnections sets the strategy for allocating inbound connections to the service across + proxy threads. The only supported value is exact_balance. By default, no connection balancing is used. + Refer to the Envoy Connection Balance config for details. + type: string + destination: + description: |- + Destination is an address(es)/port combination that represents an endpoint + outside the mesh. This is only valid when the mesh is configured in "transparent" + mode. Destinations live outside of Consul's catalog, and because of this, they + do not require an artificial node to be created. + properties: + addresses: + description: |- + Addresses is a list of IPs and/or hostnames that can be dialed + and routed through a terminating gateway. + items: + type: string + type: array + port: + description: |- + Port is the port that can be dialed on any of the addresses in this + Destination. + format: int32 + type: integer + type: object + envoyExtensions: + description: EnvoyExtensions are a list of extensions to modify Envoy + proxy configuration. + items: + description: EnvoyExtension has configuration for an extension that + patches Envoy resources. + properties: + arguments: + type: object + x-kubernetes-preserve-unknown-fields: true + name: + type: string + required: + type: boolean + type: object + type: array + expose: + description: Expose controls the default expose path configuration + for Envoy. + properties: + checks: + description: |- + Checks defines whether paths associated with Consul checks will be exposed. + This flag triggers exposing all HTTP and GRPC check paths registered for the service. + type: boolean + paths: + description: Paths is the list of paths exposed through the proxy. + items: + properties: + listenerPort: + description: ListenerPort defines the port of the proxy's + listener for exposed paths. + type: integer + localPathPort: + description: LocalPathPort is the port that the service + is listening on for the given path. + type: integer + path: + description: Path is the path to expose through the proxy, + ie. "/metrics". + type: string + protocol: + description: |- + Protocol describes the upstream's service protocol. + Valid values are "http" and "http2", defaults to "http". + type: string + type: object + type: array + type: object + externalSNI: + description: |- + ExternalSNI is an optional setting that allows for the TLS SNI value + to be changed to a non-connect value when federating with an external system. + type: string + localConnectTimeoutMs: + description: |- + LocalConnectTimeoutMs is the number of milliseconds allowed to make connections to the local application + instance before timing out. Defaults to 5000. + type: integer + localRequestTimeoutMs: + description: |- + LocalRequestTimeoutMs is the timeout for HTTP requests to the local application instance in milliseconds. + Applies to HTTP-based protocols only. If not specified, inherits the Envoy default for + route timeouts (15s). + type: integer + maxInboundConnections: + description: |- + MaxInboundConnections is the maximum number of concurrent inbound connections to + each service instance. Defaults to 0 (using consul's default) if not set. + type: integer + meshGateway: + description: MeshGateway controls the default mesh gateway configuration + for this service. + properties: + mode: + description: |- + Mode is the mode that should be used for the upstream connection. + One of none, local, or remote. + type: string + type: object + mode: + description: |- + Mode can be one of "direct" or "transparent". "transparent" represents that inbound and outbound + application traffic is being captured and redirected through the proxy. This mode does not + enable the traffic redirection itself. Instead it signals Consul to configure Envoy as if + traffic is already being redirected. "direct" represents that the proxy's listeners must be + dialed directly by the local application and other proxies. + Note: This cannot be set using the CRD and should be set using annotations on the + services that are part of the mesh. + type: string + mutualTLSMode: + description: |- + MutualTLSMode controls whether mutual TLS is required for all incoming + connections when transparent proxy is enabled. This can be set to + "permissive" or "strict". "strict" is the default which requires mutual + TLS for incoming connections. In the insecure "permissive" mode, + connections to the sidecar proxy public listener port require mutual + TLS, but connections to the service port do not require mutual TLS and + are proxied to the application unmodified. Note: Intentions are not + enforced for non-mTLS connections. To keep your services secure, we + recommend using "strict" mode whenever possible and enabling + "permissive" mode only when necessary. + type: string + protocol: + description: |- + Protocol sets the protocol of the service. This is used by Connect proxies for + things like observability features and to unlock usage of the + service-splitter and service-router config entries for a service. + type: string + rateLimits: + description: |- + RateLimits is rate limiting configuration that is applied to + inbound traffic for a service. Rate limiting is a Consul enterprise feature. + properties: + instanceLevel: + description: |- + InstanceLevel represents rate limit configuration + that is applied per service instance. + properties: + requestsMaxBurst: + description: |- + RequestsMaxBurst is the maximum number of requests that can be sent + in a burst. Should be equal to or greater than RequestsPerSecond. + If unset, defaults to RequestsPerSecond. + + + Internally, this is the maximum size of the token bucket used for rate limiting. + type: integer + requestsPerSecond: + description: |- + RequestsPerSecond is the average number of requests per second that can be + made without being throttled. This field is required if RequestsMaxBurst + is set. The allowed number of requests may exceed RequestsPerSecond up to + the value specified in RequestsMaxBurst. + + + Internally, this is the refill rate of the token bucket used for rate limiting. + type: integer + routes: + description: |- + Routes is a list of rate limits applied to specific routes. + For a given request, the first matching route will be applied, if any. + Overrides any top-level configuration. + items: + properties: + pathExact: + description: Exact path to match. Exactly one of PathExact, + PathPrefix, or PathRegex must be specified. + type: string + pathPrefix: + description: Prefix to match. Exactly one of PathExact, + PathPrefix, or PathRegex must be specified. + type: string + pathRegex: + description: Regex to match. Exactly one of PathExact, + PathPrefix, or PathRegex must be specified. + type: string + requestsMaxBurst: + description: |- + RequestsMaxBurst is the maximum number of requests that can be sent + in a burst. Should be equal to or greater than RequestsPerSecond. If unset, + defaults to RequestsPerSecond. Internally, this is the maximum size of the token + bucket used for rate limiting. + type: integer + requestsPerSecond: + description: |- + RequestsPerSecond is the average number of requests per + second that can be made without being throttled. This field is required + if RequestsMaxBurst is set. The allowed number of requests may exceed + RequestsPerSecond up to the value specified in RequestsMaxBurst. + Internally, this is the refill rate of the token bucket used for rate limiting. + type: integer + type: object + type: array + type: object + type: object + transparentProxy: + description: |- + TransparentProxy controls configuration specific to proxies in transparent mode. + Note: This cannot be set using the CRD and should be set using annotations on the + services that are part of the mesh. + properties: + dialedDirectly: + description: |- + DialedDirectly indicates whether transparent proxies can dial this proxy instance directly. + The discovery chain is not considered when dialing a service instance directly. + This setting is useful when addressing stateful services, such as a database cluster with a leader node. + type: boolean + outboundListenerPort: + description: |- + OutboundListenerPort is the port of the listener where outbound application + traffic is being redirected to. + type: integer + type: object + upstreamConfig: + description: |- + UpstreamConfig controls default configuration settings that apply across all upstreams, + and per-upstream configuration overrides. Note that per-upstream configuration applies + across all federated datacenters to the pairing of source and upstream destination services. + properties: + defaults: + description: |- + Defaults contains default configuration for all upstreams of a given + service. The name field must be empty. + properties: + connectTimeoutMs: + description: |- + ConnectTimeoutMs is the number of milliseconds to timeout making a new + connection to this upstream. Defaults to 5000 (5 seconds) if not set. + type: integer + envoyClusterJSON: + description: |- + EnvoyClusterJSON is a complete override ("escape hatch") for the upstream's + cluster. The Connect client TLS certificate and context will be injected + overriding any TLS settings present. + Note: This escape hatch is NOT compatible with the discovery chain and + will be ignored if a discovery chain is active. + type: string + envoyListenerJSON: + description: |- + EnvoyListenerJSON is a complete override ("escape hatch") for the upstream's + listener. + Note: This escape hatch is NOT compatible with the discovery chain and + will be ignored if a discovery chain is active. + type: string + limits: + description: |- + Limits are the set of limits that are applied to the proxy for a specific upstream of a + service instance. + properties: + maxConcurrentRequests: + description: |- + MaxConcurrentRequests is the maximum number of in-flight requests that will be allowed + to the upstream cluster at a point in time. This is mostly applicable to HTTP/2 + clusters since all HTTP/1.1 requests are limited by MaxConnections. + type: integer + maxConnections: + description: |- + MaxConnections is the maximum number of connections the local proxy can + make to the upstream service. + type: integer + maxPendingRequests: + description: |- + MaxPendingRequests is the maximum number of requests that will be queued + waiting for an available connection. This is mostly applicable to HTTP/1.1 + clusters since all HTTP/2 requests are streamed over a single + connection. + type: integer + type: object + meshGateway: + description: MeshGatewayConfig controls how Mesh Gateways + are configured and used. + properties: + mode: + description: |- + Mode is the mode that should be used for the upstream connection. + One of none, local, or remote. + type: string + type: object + name: + description: Name is only accepted within service ServiceDefaultsSpec.UpstreamConfig.Overrides + config entry. + type: string + namespace: + description: Namespace is only accepted within service ServiceDefaultsSpec.UpstreamConfig.Overrides + config entry. + type: string + partition: + description: Partition is only accepted within service ServiceDefaultsSpec.UpstreamConfig.Overrides + config entry. + type: string + passiveHealthCheck: + description: |- + PassiveHealthCheck configuration determines how upstream proxy instances will + be monitored for removal from the load balancing pool. + properties: + baseEjectionTime: + description: |- + The base time that a host is ejected for. The real time is equal to the base time + multiplied by the number of times the host has been ejected and is capped by + max_ejection_time (Default 300s). Defaults to 30s. + type: string + enforcingConsecutive5xx: + description: |- + EnforcingConsecutive5xx is the % chance that a host will be actually ejected + when an outlier status is detected through consecutive 5xx. + This setting can be used to disable ejection or to ramp it up slowly. + Ex. Setting this to 10 will make it a 10% chance that the host will be ejected. + format: int32 + type: integer + interval: + description: |- + Interval between health check analysis sweeps. Each sweep may remove + hosts or return hosts to the pool. Ex. setting this to "10s" will set + the interval to 10 seconds. + type: string + maxEjectionPercent: + description: |- + The maximum % of an upstream cluster that can be ejected due to outlier detection. + Defaults to 10% but will eject at least one host regardless of the value. + format: int32 + type: integer + maxFailures: + description: |- + MaxFailures is the count of consecutive failures that results in a host + being removed from the pool. + format: int32 + type: integer + type: object + peer: + description: Peer is only accepted within service ServiceDefaultsSpec.UpstreamConfig.Overrides + config entry. + type: string + protocol: + description: |- + Protocol describes the upstream's service protocol. Valid values are "tcp", + "http" and "grpc". Anything else is treated as tcp. This enables protocol + aware features like per-request metrics and connection pooling, tracing, + routing etc. + type: string + type: object + overrides: + description: |- + Overrides is a slice of per-service configuration. The name field is + required. + items: + properties: + connectTimeoutMs: + description: |- + ConnectTimeoutMs is the number of milliseconds to timeout making a new + connection to this upstream. Defaults to 5000 (5 seconds) if not set. + type: integer + envoyClusterJSON: + description: |- + EnvoyClusterJSON is a complete override ("escape hatch") for the upstream's + cluster. The Connect client TLS certificate and context will be injected + overriding any TLS settings present. + Note: This escape hatch is NOT compatible with the discovery chain and + will be ignored if a discovery chain is active. + type: string + envoyListenerJSON: + description: |- + EnvoyListenerJSON is a complete override ("escape hatch") for the upstream's + listener. + Note: This escape hatch is NOT compatible with the discovery chain and + will be ignored if a discovery chain is active. + type: string + limits: + description: |- + Limits are the set of limits that are applied to the proxy for a specific upstream of a + service instance. + properties: + maxConcurrentRequests: + description: |- + MaxConcurrentRequests is the maximum number of in-flight requests that will be allowed + to the upstream cluster at a point in time. This is mostly applicable to HTTP/2 + clusters since all HTTP/1.1 requests are limited by MaxConnections. + type: integer + maxConnections: + description: |- + MaxConnections is the maximum number of connections the local proxy can + make to the upstream service. + type: integer + maxPendingRequests: + description: |- + MaxPendingRequests is the maximum number of requests that will be queued + waiting for an available connection. This is mostly applicable to HTTP/1.1 + clusters since all HTTP/2 requests are streamed over a single + connection. + type: integer + type: object + meshGateway: + description: MeshGatewayConfig controls how Mesh Gateways + are configured and used. + properties: + mode: + description: |- + Mode is the mode that should be used for the upstream connection. + One of none, local, or remote. + type: string + type: object + name: + description: Name is only accepted within service ServiceDefaultsSpec.UpstreamConfig.Overrides + config entry. + type: string + namespace: + description: Namespace is only accepted within service ServiceDefaultsSpec.UpstreamConfig.Overrides + config entry. + type: string + partition: + description: Partition is only accepted within service ServiceDefaultsSpec.UpstreamConfig.Overrides + config entry. + type: string + passiveHealthCheck: + description: |- + PassiveHealthCheck configuration determines how upstream proxy instances will + be monitored for removal from the load balancing pool. + properties: + baseEjectionTime: + description: |- + The base time that a host is ejected for. The real time is equal to the base time + multiplied by the number of times the host has been ejected and is capped by + max_ejection_time (Default 300s). Defaults to 30s. + type: string + enforcingConsecutive5xx: + description: |- + EnforcingConsecutive5xx is the % chance that a host will be actually ejected + when an outlier status is detected through consecutive 5xx. + This setting can be used to disable ejection or to ramp it up slowly. + Ex. Setting this to 10 will make it a 10% chance that the host will be ejected. + format: int32 + type: integer + interval: + description: |- + Interval between health check analysis sweeps. Each sweep may remove + hosts or return hosts to the pool. Ex. setting this to "10s" will set + the interval to 10 seconds. + type: string + maxEjectionPercent: + description: |- + The maximum % of an upstream cluster that can be ejected due to outlier detection. + Defaults to 10% but will eject at least one host regardless of the value. + format: int32 + type: integer + maxFailures: + description: |- + MaxFailures is the count of consecutive failures that results in a host + being removed from the pool. + format: int32 + type: integer + type: object + peer: + description: Peer is only accepted within service ServiceDefaultsSpec.UpstreamConfig.Overrides + config entry. + type: string + protocol: + description: |- + Protocol describes the upstream's service protocol. Valid values are "tcp", + "http" and "grpc". Anything else is treated as tcp. This enables protocol + aware features like per-request metrics and connection pooling, tracing, + routing etc. + type: string + type: object + type: array + type: object + type: object + status: + properties: + conditions: + description: Conditions indicate the latest available observations + of a resource's current state. + items: + description: |- + Conditions define a readiness condition for a Consul resource. + See: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties + properties: + lastTransitionTime: + description: LastTransitionTime is the 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 condition. + type: string + required: + - status + - type + type: object + type: array + lastSyncedTime: + description: LastSyncedTime is the last time the resource successfully + synced with Consul. + format: date-time + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- end }} diff --git a/kubernetes-vault/consul/templates/crd-serviceintentions.yaml b/kubernetes-vault/consul/templates/crd-serviceintentions.yaml new file mode 100644 index 0000000..72159ec --- /dev/null +++ b/kubernetes-vault/consul/templates/crd-serviceintentions.yaml @@ -0,0 +1,310 @@ +{{- if .Values.connectInject.enabled }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: crd + name: serviceintentions.consul.hashicorp.com +spec: + group: consul.hashicorp.com + names: + kind: ServiceIntentions + listKind: ServiceIntentionsList + plural: serviceintentions + shortNames: + - service-intentions + singular: serviceintentions + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The sync status of the resource with Consul + jsonPath: .status.conditions[?(@.type=="Synced")].status + name: Synced + type: string + - description: The last successful synced time of the resource with Consul + jsonPath: .status.lastSyncedTime + name: Last Synced + type: date + - description: The age of the resource + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: ServiceIntentions is the Schema for the serviceintentions 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: ServiceIntentionsSpec defines the desired state of ServiceIntentions. + properties: + destination: + description: Destination is the intention destination that will have + the authorization granted to. + properties: + name: + description: |- + Name is the destination of all intentions defined in this config entry. + This may be set to the wildcard character (*) to match + all services that don't otherwise have intentions defined. + type: string + namespace: + description: |- + Namespace specifies the namespace the config entry will apply to. + This may be set to the wildcard character (*) to match all services + in all namespaces that don't otherwise have intentions defined. + type: string + type: object + jwt: + description: JWT specifies the configuration to validate a JSON Web + Token for all incoming requests. + properties: + providers: + description: Providers is a list of providers to consider when + verifying a JWT. + items: + properties: + name: + description: |- + Name is the name of the JWT provider. There MUST be a corresponding + "jwt-provider" config entry with this name. + type: string + verifyClaims: + description: VerifyClaims is a list of additional claims + to verify in a JWT's payload. + items: + properties: + path: + description: Path is the path to the claim in the + token JSON. + items: + type: string + type: array + value: + description: |- + Value is the expected value at the given path. If the type at the path + is a list then we verify that this value is contained in the list. If + the type at the path is a string then we verify that this value matches. + type: string + type: object + type: array + type: object + type: array + type: object + sources: + description: |- + Sources is the list of all intention sources and the authorization granted to those sources. + The order of this list does not matter, but out of convenience Consul will always store this + reverse sorted by intention precedence, as that is the order that they will be evaluated at enforcement time. + items: + properties: + action: + description: |- + Action is required for an L4 intention, and should be set to one of + "allow" or "deny" for the action that should be taken if this intention matches a request. + type: string + description: + description: Description for the intention. This is not used + by Consul, but is presented in API responses to assist tooling. + type: string + name: + description: |- + Name is the source of the intention. This is the name of a + Consul service. The service doesn't need to be registered. + type: string + namespace: + description: Namespace is the namespace for the Name parameter. + type: string + partition: + description: Partition is the Admin Partition for the Name parameter. + type: string + peer: + description: Peer is the peer name for the Name parameter. + type: string + permissions: + description: |- + Permissions is the list of all additional L7 attributes that extend the intention match criteria. + Permission precedence is applied top to bottom. For any given request the first permission to match + in the list is terminal and stops further evaluation. As with L4 intentions, traffic that fails to + match any of the provided permissions in this intention will be subject to the default intention + behavior is defined by the default ACL policy. This should be omitted for an L4 intention + as it is mutually exclusive with the Action field. + items: + properties: + action: + description: |- + Action is one of "allow" or "deny" for the action that + should be taken if this permission matches a request. + type: string + http: + description: HTTP is a set of HTTP-specific authorization + criteria. + properties: + header: + description: |- + Header is a set of criteria that can match on HTTP request headers. + If more than one is configured all must match for the overall match to apply. + items: + properties: + exact: + description: Exact matches if the header with + the given name is this value. + type: string + invert: + description: Invert inverts the logic of the + match. + type: boolean + name: + description: Name is the name of the header + to match. + type: string + prefix: + description: Prefix matches if the header with + the given name has this prefix. + type: string + present: + description: Present matches if the header with + the given name is present with any value. + type: boolean + regex: + description: Regex matches if the header with + the given name matches this pattern. + type: string + suffix: + description: Suffix matches if the header with + the given name has this suffix. + type: string + type: object + type: array + methods: + description: |- + Methods is a list of HTTP methods for which this match applies. If unspecified + all HTTP methods are matched. If provided the names must be a valid method. + items: + type: string + type: array + pathExact: + description: PathExact is the exact path to match + on the HTTP request path. + type: string + pathPrefix: + description: PathPrefix is the path prefix to match + on the HTTP request path. + type: string + pathRegex: + description: PathRegex is the regular expression to + match on the HTTP request path. + type: string + type: object + jwt: + description: JWT specifies configuration to validate a + JSON Web Token for incoming requests. + properties: + providers: + description: Providers is a list of providers to consider + when verifying a JWT. + items: + properties: + name: + description: |- + Name is the name of the JWT provider. There MUST be a corresponding + "jwt-provider" config entry with this name. + type: string + verifyClaims: + description: VerifyClaims is a list of additional + claims to verify in a JWT's payload. + items: + properties: + path: + description: Path is the path to the claim + in the token JSON. + items: + type: string + type: array + value: + description: |- + Value is the expected value at the given path. If the type at the path + is a list then we verify that this value is contained in the list. If + the type at the path is a string then we verify that this value matches. + type: string + type: object + type: array + type: object + type: array + type: object + type: object + type: array + samenessGroup: + description: SamenessGroup is the name of the sameness group, + if applicable. + type: string + type: object + type: array + type: object + status: + properties: + conditions: + description: Conditions indicate the latest available observations + of a resource's current state. + items: + description: |- + Conditions define a readiness condition for a Consul resource. + See: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties + properties: + lastTransitionTime: + description: LastTransitionTime is the 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 condition. + type: string + required: + - status + - type + type: object + type: array + lastSyncedTime: + description: LastSyncedTime is the last time the resource successfully + synced with Consul. + format: date-time + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- end }} diff --git a/kubernetes-vault/consul/templates/crd-serviceresolvers.yaml b/kubernetes-vault/consul/templates/crd-serviceresolvers.yaml new file mode 100644 index 0000000..9367d6d --- /dev/null +++ b/kubernetes-vault/consul/templates/crd-serviceresolvers.yaml @@ -0,0 +1,372 @@ +{{- if .Values.connectInject.enabled }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: crd + name: serviceresolvers.consul.hashicorp.com +spec: + group: consul.hashicorp.com + names: + kind: ServiceResolver + listKind: ServiceResolverList + plural: serviceresolvers + shortNames: + - service-resolver + singular: serviceresolver + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The sync status of the resource with Consul + jsonPath: .status.conditions[?(@.type=="Synced")].status + name: Synced + type: string + - description: The last successful synced time of the resource with Consul + jsonPath: .status.lastSyncedTime + name: Last Synced + type: date + - description: The age of the resource + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: ServiceResolver is the Schema for the serviceresolvers 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: ServiceResolverSpec defines the desired state of ServiceResolver. + properties: + connectTimeout: + description: |- + ConnectTimeout is the timeout for establishing new network connections + to this service. + type: string + defaultSubset: + description: |- + DefaultSubset is the subset to use when no explicit subset is requested. + If empty the unnamed subset is used. + type: string + failover: + additionalProperties: + properties: + datacenters: + description: Datacenters is a fixed list of datacenters to try + during failover. + items: + type: string + type: array + namespace: + description: |- + Namespace is the namespace to resolve the requested service from to form + the failover group of instances. If empty the current namespace is used. + type: string + policy: + description: Policy specifies the exact mechanism used for failover. + properties: + mode: + description: |- + Mode specifies the type of failover that will be performed. Valid values are + "sequential", "" (equivalent to "sequential") and "order-by-locality". + type: string + regions: + description: |- + Regions is the ordered list of the regions of the failover targets. + Valid values can be "us-west-1", "us-west-2", and so on. + items: + type: string + type: array + type: object + samenessGroup: + description: SamenessGroup is the name of the sameness group + to try during failover. + type: string + service: + description: |- + Service is the service to resolve instead of the default as the failover + group of instances during failover. + type: string + serviceSubset: + description: |- + ServiceSubset is the named subset of the requested service to resolve as + the failover group of instances. If empty the default subset for the + requested service is used. + type: string + targets: + description: Targets specifies a fixed list of failover targets + to try during failover. + items: + properties: + datacenter: + description: Datacenter specifies the datacenter to try + during failover. + type: string + namespace: + description: Namespace specifies the namespace to try + during failover. + type: string + partition: + description: Partition specifies the partition to try + during failover. + type: string + peer: + description: Peer specifies the name of the cluster peer + to try during failover. + type: string + service: + description: Service specifies the name of the service + to try during failover. + type: string + serviceSubset: + description: ServiceSubset specifies the service subset + to try during failover. + type: string + type: object + type: array + type: object + description: |- + Failover controls when and how to reroute traffic to an alternate pool of + service instances. + The map is keyed by the service subset it applies to and the special + string "*" is a wildcard that applies to any subset not otherwise + specified here. + type: object + loadBalancer: + description: |- + LoadBalancer determines the load balancing policy and configuration for services + issuing requests to this upstream service. + properties: + hashPolicies: + description: |- + HashPolicies is a list of hash policies to use for hashing load balancing algorithms. + Hash policies are evaluated individually and combined such that identical lists + result in the same hash. + If no hash policies are present, or none are successfully evaluated, + then a random backend host will be selected. + items: + properties: + cookieConfig: + description: CookieConfig contains configuration for the + "cookie" hash policy type. + properties: + path: + description: Path is the path to set for the cookie. + type: string + session: + description: Session determines whether to generate + a session cookie with no expiration. + type: boolean + ttl: + description: TTL is the ttl for generated cookies. Cannot + be specified for session cookies. + type: string + type: object + field: + description: |- + Field is the attribute type to hash on. + Must be one of "header", "cookie", or "query_parameter". + Cannot be specified along with sourceIP. + type: string + fieldValue: + description: |- + FieldValue is the value to hash. + ie. header name, cookie name, URL query parameter name + Cannot be specified along with sourceIP. + type: string + sourceIP: + description: |- + SourceIP determines whether the hash should be of the source IP rather than of a field and field value. + Cannot be specified along with field or fieldValue. + type: boolean + terminal: + description: |- + Terminal will short circuit the computation of the hash when multiple hash policies are present. + If a hash is computed when a Terminal policy is evaluated, + then that hash will be used and subsequent hash policies will be ignored. + type: boolean + type: object + type: array + leastRequestConfig: + description: LeastRequestConfig contains configuration for the + "leastRequest" policy type. + properties: + choiceCount: + description: ChoiceCount determines the number of random healthy + hosts from which to select the one with the least requests. + format: int32 + type: integer + type: object + policy: + description: Policy is the load balancing policy used to select + a host. + type: string + ringHashConfig: + description: RingHashConfig contains configuration for the "ringHash" + policy type. + properties: + maximumRingSize: + description: MaximumRingSize determines the maximum number + of entries in the hash ring. + format: int64 + type: integer + minimumRingSize: + description: MinimumRingSize determines the minimum number + of entries in the hash ring. + format: int64 + type: integer + type: object + type: object + prioritizeByLocality: + description: |- + PrioritizeByLocality controls whether the locality of services within the + local partition will be used to prioritize connectivity. + properties: + mode: + description: |- + Mode specifies the type of prioritization that will be performed + when selecting nodes in the local partition. + Valid values are: "" (default "none"), "none", and "failover". + type: string + type: object + redirect: + description: |- + Redirect when configured, all attempts to resolve the service this + resolver defines will be substituted for the supplied redirect + EXCEPT when the redirect has already been applied. + When substituting the supplied redirect, all other fields besides + Kind, Name, and Redirect will be ignored. + properties: + datacenter: + description: |- + Datacenter is the datacenter to resolve the service from instead of the + current one. + type: string + namespace: + description: |- + Namespace is the Consul namespace to resolve the service from instead of + the current namespace. If empty the current namespace is assumed. + type: string + partition: + description: |- + Partition is the Consul partition to resolve the service from instead of + the current partition. If empty the current partition is assumed. + type: string + peer: + description: |- + Peer is the name of the cluster peer to resolve the service from instead + of the current one. + type: string + samenessGroup: + description: SamenessGroup is the name of the sameness group to + resolve the service from instead of the current one. + type: string + service: + description: Service is a service to resolve instead of the current + service. + type: string + serviceSubset: + description: |- + ServiceSubset is a named subset of the given service to resolve instead + of one defined as that service's DefaultSubset If empty the default + subset is used. + type: string + type: object + requestTimeout: + description: |- + RequestTimeout is the timeout for receiving an HTTP response from this + service before the connection is terminated. + type: string + subsets: + additionalProperties: + properties: + filter: + description: |- + Filter is the filter expression to be used for selecting instances of the + requested service. If empty all healthy instances are returned. This + expression can filter on the same selectors as the Health API endpoint. + type: string + onlyPassing: + description: |- + OnlyPassing specifies the behavior of the resolver's health check + interpretation. If this is set to false, instances with checks in the + passing as well as the warning states will be considered healthy. If this + is set to true, only instances with checks in the passing state will be + considered healthy. + type: boolean + type: object + description: |- + Subsets is map of subset name to subset definition for all usable named + subsets of this service. The map key is the name of the subset and all + names must be valid DNS subdomain elements. + This may be empty, in which case only the unnamed default subset will + be usable. + type: object + type: object + status: + properties: + conditions: + description: Conditions indicate the latest available observations + of a resource's current state. + items: + description: |- + Conditions define a readiness condition for a Consul resource. + See: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties + properties: + lastTransitionTime: + description: LastTransitionTime is the 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 condition. + type: string + required: + - status + - type + type: object + type: array + lastSyncedTime: + description: LastSyncedTime is the last time the resource successfully + synced with Consul. + format: date-time + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- end }} diff --git a/kubernetes-vault/consul/templates/crd-servicerouters.yaml b/kubernetes-vault/consul/templates/crd-servicerouters.yaml new file mode 100644 index 0000000..4d62149 --- /dev/null +++ b/kubernetes-vault/consul/templates/crd-servicerouters.yaml @@ -0,0 +1,335 @@ +{{- if .Values.connectInject.enabled }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: crd + name: servicerouters.consul.hashicorp.com +spec: + group: consul.hashicorp.com + names: + kind: ServiceRouter + listKind: ServiceRouterList + plural: servicerouters + shortNames: + - service-router + singular: servicerouter + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The sync status of the resource with Consul + jsonPath: .status.conditions[?(@.type=="Synced")].status + name: Synced + type: string + - description: The last successful synced time of the resource with Consul + jsonPath: .status.lastSyncedTime + name: Last Synced + type: date + - description: The age of the resource + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: ServiceRouter is the Schema for the servicerouters 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: ServiceRouterSpec defines the desired state of ServiceRouter. + properties: + routes: + description: |- + Routes are the list of routes to consider when processing L7 requests. + The first route to match in the list is terminal and stops further + evaluation. Traffic that fails to match any of the provided routes will + be routed to the default service. + items: + properties: + destination: + description: Destination controls how to proxy the matching + request(s) to a service. + properties: + idleTimeout: + description: |- + IdleTimeout is total amount of time permitted + for the request stream to be idle. + type: string + namespace: + description: |- + Namespace is the Consul namespace to resolve the service from instead of + the current namespace. If empty the current namespace is assumed. + type: string + numRetries: + description: NumRetries is the number of times to retry + the request when a retryable result occurs + format: int32 + type: integer + partition: + description: |- + Partition is the Consul partition to resolve the service from instead of + the current partition. If empty the current partition is assumed. + type: string + prefixRewrite: + description: |- + PrefixRewrite defines how to rewrite the HTTP request path before proxying + it to its final destination. + This requires that either match.http.pathPrefix or match.http.pathExact + be configured on this route. + type: string + requestHeaders: + description: Allow HTTP header manipulation to be configured. + properties: + add: + additionalProperties: + type: string + description: |- + Add is a set of name -> value pairs that should be appended to the request + or response (i.e. allowing duplicates if the same header already exists). + type: object + remove: + description: |- + Remove is the set of header names that should be stripped from the request + or response. + items: + type: string + type: array + set: + additionalProperties: + type: string + description: |- + Set is a set of name -> value pairs that should be added to the request or + response, overwriting any existing header values of the same name. + type: object + type: object + requestTimeout: + description: |- + RequestTimeout is the total amount of time permitted for the entire + downstream request (and retries) to be processed. + type: string + responseHeaders: + description: |- + HTTPHeaderModifiers is a set of rules for HTTP header modification that + should be performed by proxies as the request passes through them. It can + operate on either request or response headers depending on the context in + which it is used. + properties: + add: + additionalProperties: + type: string + description: |- + Add is a set of name -> value pairs that should be appended to the request + or response (i.e. allowing duplicates if the same header already exists). + type: object + remove: + description: |- + Remove is the set of header names that should be stripped from the request + or response. + items: + type: string + type: array + set: + additionalProperties: + type: string + description: |- + Set is a set of name -> value pairs that should be added to the request or + response, overwriting any existing header values of the same name. + type: object + type: object + retryOn: + description: |- + RetryOn is a flat list of conditions for Consul to retry requests based on the response from an upstream service. + Refer to the valid conditions here: https://developer.hashicorp.com/consul/docs/connect/config-entries/service-router#routes-destination-retryon + items: + type: string + type: array + retryOnConnectFailure: + description: RetryOnConnectFailure allows for connection + failure errors to trigger a retry. + type: boolean + retryOnStatusCodes: + description: RetryOnStatusCodes is a flat list of http response + status codes that are eligible for retry. + items: + format: int32 + type: integer + type: array + service: + description: |- + Service is the service to resolve instead of the default service. + If empty then the default service name is used. + type: string + serviceSubset: + description: |- + ServiceSubset is a named subset of the given service to resolve instead + of the one defined as that service's DefaultSubset. + If empty, the default subset is used. + type: string + type: object + match: + description: |- + Match is a set of criteria that can match incoming L7 requests. + If empty or omitted it acts as a catch-all. + properties: + http: + description: HTTP is a set of http-specific match criteria. + properties: + caseInsensitive: + description: CaseInsensitive configures PathExact and + PathPrefix matches to ignore upper/lower casing. + type: boolean + header: + description: |- + Header is a set of criteria that can match on HTTP request headers. + If more than one is configured all must match for the overall match to apply. + items: + properties: + exact: + description: Exact will match if the header with + the given name is this value. + type: string + invert: + description: Invert inverts the logic of the match. + type: boolean + name: + description: Name is the name of the header to + match. + type: string + prefix: + description: Prefix will match if the header with + the given name has this prefix. + type: string + present: + description: Present will match if the header + with the given name is present with any value. + type: boolean + regex: + description: Regex will match if the header with + the given name matches this pattern. + type: string + suffix: + description: Suffix will match if the header with + the given name has this suffix. + type: string + required: + - name + type: object + type: array + methods: + description: |- + Methods is a list of HTTP methods for which this match applies. + If unspecified all http methods are matched. + items: + type: string + type: array + pathExact: + description: PathExact is an exact path to match on + the HTTP request path. + type: string + pathPrefix: + description: PathPrefix is a path prefix to match on + the HTTP request path. + type: string + pathRegex: + description: PathRegex is a regular expression to match + on the HTTP request path. + type: string + queryParam: + description: |- + QueryParam is a set of criteria that can match on HTTP query parameters. + If more than one is configured all must match for the overall match to apply. + items: + properties: + exact: + description: Exact will match if the query parameter + with the given name is this value. + type: string + name: + description: Name is the name of the query parameter + to match on. + type: string + present: + description: |- + Present will match if the query parameter with the given name is present + with any value. + type: boolean + regex: + description: Regex will match if the query parameter + with the given name matches this pattern. + type: string + required: + - name + type: object + type: array + type: object + type: object + type: object + type: array + type: object + status: + properties: + conditions: + description: Conditions indicate the latest available observations + of a resource's current state. + items: + description: |- + Conditions define a readiness condition for a Consul resource. + See: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties + properties: + lastTransitionTime: + description: LastTransitionTime is the 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 condition. + type: string + required: + - status + - type + type: object + type: array + lastSyncedTime: + description: LastSyncedTime is the last time the resource successfully + synced with Consul. + format: date-time + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- end }} diff --git a/kubernetes-vault/consul/templates/crd-servicesplitters.yaml b/kubernetes-vault/consul/templates/crd-servicesplitters.yaml new file mode 100644 index 0000000..704ad5d --- /dev/null +++ b/kubernetes-vault/consul/templates/crd-servicesplitters.yaml @@ -0,0 +1,194 @@ +{{- if .Values.connectInject.enabled }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: crd + name: servicesplitters.consul.hashicorp.com +spec: + group: consul.hashicorp.com + names: + kind: ServiceSplitter + listKind: ServiceSplitterList + plural: servicesplitters + shortNames: + - service-splitter + singular: servicesplitter + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The sync status of the resource with Consul + jsonPath: .status.conditions[?(@.type=="Synced")].status + name: Synced + type: string + - description: The last successful synced time of the resource with Consul + jsonPath: .status.lastSyncedTime + name: Last Synced + type: date + - description: The age of the resource + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: ServiceSplitter is the Schema for the servicesplitters 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: ServiceSplitterSpec defines the desired state of ServiceSplitter. + properties: + splits: + description: |- + Splits defines how much traffic to send to which set of service instances during a traffic split. + The sum of weights across all splits must add up to 100. + items: + properties: + namespace: + description: |- + Namespace is the Consul namespace to resolve the service from instead of + the current namespace. If empty the current namespace is assumed. + type: string + partition: + description: |- + Partition is the Consul partition to resolve the service from instead of + the current partition. If empty the current partition is assumed. + type: string + requestHeaders: + description: Allow HTTP header manipulation to be configured. + properties: + add: + additionalProperties: + type: string + description: |- + Add is a set of name -> value pairs that should be appended to the request + or response (i.e. allowing duplicates if the same header already exists). + type: object + remove: + description: |- + Remove is the set of header names that should be stripped from the request + or response. + items: + type: string + type: array + set: + additionalProperties: + type: string + description: |- + Set is a set of name -> value pairs that should be added to the request or + response, overwriting any existing header values of the same name. + type: object + type: object + responseHeaders: + description: |- + HTTPHeaderModifiers is a set of rules for HTTP header modification that + should be performed by proxies as the request passes through them. It can + operate on either request or response headers depending on the context in + which it is used. + properties: + add: + additionalProperties: + type: string + description: |- + Add is a set of name -> value pairs that should be appended to the request + or response (i.e. allowing duplicates if the same header already exists). + type: object + remove: + description: |- + Remove is the set of header names that should be stripped from the request + or response. + items: + type: string + type: array + set: + additionalProperties: + type: string + description: |- + Set is a set of name -> value pairs that should be added to the request or + response, overwriting any existing header values of the same name. + type: object + type: object + service: + description: Service is the service to resolve instead of the + default. + type: string + serviceSubset: + description: |- + ServiceSubset is a named subset of the given service to resolve instead of one defined + as that service's DefaultSubset. If empty the default subset is used. + type: string + weight: + description: |- + Weight is a value between 0 and 100 reflecting what portion of traffic should be directed to this split. + The smallest representable weight is 1/10000 or .01%. + type: number + type: object + type: array + type: object + status: + properties: + conditions: + description: Conditions indicate the latest available observations + of a resource's current state. + items: + description: |- + Conditions define a readiness condition for a Consul resource. + See: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties + properties: + lastTransitionTime: + description: LastTransitionTime is the 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 condition. + type: string + required: + - status + - type + type: object + type: array + lastSyncedTime: + description: LastSyncedTime is the last time the resource successfully + synced with Consul. + format: date-time + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- end }} diff --git a/kubernetes-vault/consul/templates/crd-tcproutes-external.yaml b/kubernetes-vault/consul/templates/crd-tcproutes-external.yaml new file mode 100644 index 0000000..a57a329 --- /dev/null +++ b/kubernetes-vault/consul/templates/crd-tcproutes-external.yaml @@ -0,0 +1,281 @@ +{{- if and .Values.connectInject.enabled (or .Values.connectInject.apiGateway.manageExternalCRDs .Values.connectInject.apiGateway.manageNonStandardCRDs ) }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/1538 + gateway.networking.k8s.io/bundle-version: v0.6.2 + gateway.networking.k8s.io/channel: experimental + creationTimestamp: null + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: crd + name: tcproutes.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: TCPRoute + listKind: TCPRouteList + plural: tcproutes + singular: tcproute + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha2 + schema: + openAPIV3Schema: + description: TCPRoute provides a way to route TCP requests. When combined with a Gateway listener, it can be used to forward connections on the port specified by the listener to a set of backends specified by the TCPRoute. + 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 TCPRoute. + properties: + 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: + description: Rules are a list of TCP matchers and actions. + items: + description: TCPRouteRule is the configuration for a given rule. + properties: + backendRefs: + description: "BackendRefs defines the backend(s) where matching requests should be sent. If unspecified or invalid (refers to a non-existent resource or a Service with no endpoints), the underlying implementation MUST actively reject connection attempts to this backend. Connection rejections must respect weight; if an invalid backend is requested to have 80% of connections, then 80% of connections must be rejected instead. \n Support: Core for Kubernetes Service \n Support: Implementation-specific for any other resource \n Support for weight: Extended" + items: + description: "BackendRef defines how a Route should forward a request to a Kubernetes resource. \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." + 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 + required: + - name + type: object + maxItems: 16 + minItems: 1 + type: array + type: object + maxItems: 16 + minItems: 1 + type: array + required: + - rules + type: object + status: + description: Status defines the current state of TCPRoute. + 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 \ttype FooStatus struct{ \t // Represents the observations of a foo's current state. \t // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" \t // +patchMergeKey=type \t // +patchStrategy=merge \t // +listType=map \t // +listMapKey=type \t Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n \t // other fields \t}" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + 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: [] + storedVersions: [] +{{- end }} diff --git a/kubernetes-vault/consul/templates/crd-tcproutes.yaml b/kubernetes-vault/consul/templates/crd-tcproutes.yaml new file mode 100644 index 0000000..a71d312 --- /dev/null +++ b/kubernetes-vault/consul/templates/crd-tcproutes.yaml @@ -0,0 +1,299 @@ +{{- if .Values.connectInject.enabled }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: crd + name: tcproutes.mesh.consul.hashicorp.com +spec: + group: mesh.consul.hashicorp.com + names: + kind: TCPRoute + listKind: TCPRouteList + plural: tcproutes + shortNames: + - tcp-route + singular: tcproute + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The sync status of the resource with Consul + jsonPath: .status.conditions[?(@.type=="Synced")].status + name: Synced + type: string + - description: The last successful synced time of the resource with Consul + jsonPath: .status.lastSyncedTime + name: Last Synced + type: date + - description: The age of the resource + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v2beta1 + schema: + openAPIV3Schema: + description: TCPRoute is the Schema for the TCP Route 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: |- + NOTE: this should align to the GAMMA/gateway-api version, or at least be + easily translatable. + + + https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1alpha2.TCPRoute + + + This is a Resource type. + properties: + parentRefs: + description: |- + ParentRefs references the resources (usually Services) that a Route wants + to be attached to. + + + It is invalid to reference an identical parent more than once. It is valid + to reference multiple distinct sections within the same parent resource. + items: + description: 'NOTE: roughly equivalent to structs.ResourceReference' + properties: + port: + description: |- + For east/west this is the name of the Consul Service port to direct traffic to + or empty to imply all. + For north/south this is TBD. + + + For more details on potential values of this field, see documentation for + Service.ServicePort. + type: string + ref: + description: |- + For east/west configuration, this should point to a Service. + For north/south it should point to a Gateway. + properties: + name: + description: Name is the user-given name of the resource + (e.g. the "billing" service). + type: string + section: + description: Section identifies which part of the resource + the condition relates to. + type: string + tenancy: + description: |- + Tenancy identifies the tenancy units (i.e. partition, namespace) in which + the resource resides. + properties: + namespace: + description: |- + Namespace further isolates resources within a partition. + https://developer.hashicorp.com/consul/docs/enterprise/namespaces + + + When using the List and WatchList endpoints, provide the wildcard value "*" + to list resources across all namespaces. + type: string + partition: + description: |- + Partition is the topmost administrative boundary within a cluster. + https://developer.hashicorp.com/consul/docs/enterprise/admin-partitions + + + When using the List and WatchList endpoints, provide the wildcard value "*" + to list resources across all partitions. + type: string + type: object + type: + description: Type identifies the resource's type. + properties: + group: + description: |- + Group describes the area of functionality to which this resource type + relates (e.g. "catalog", "authorization"). + type: string + groupVersion: + description: |- + GroupVersion is incremented when sweeping or backward-incompatible changes + are made to the group's resource types. + type: string + kind: + description: Kind identifies the specific resource type + within the group. + type: string + type: object + type: object + type: object + type: array + rules: + description: Rules are a list of TCP matchers and actions. + items: + properties: + backendRefs: + description: |- + BackendRefs defines the backend(s) where matching requests should be sent. + If unspecified or invalid (refers to a non-existent resource or a Service + with no endpoints), the underlying implementation MUST actively reject + connection attempts to this backend. Connection rejections must respect + weight; if an invalid backend is requested to have 80% of connections, + then 80% of connections must be rejected instead. + items: + properties: + backendRef: + properties: + datacenter: + type: string + port: + description: |- + For east/west this is the name of the Consul Service port to direct traffic to + or empty to imply using the same value as the parent ref. + For north/south this is TBD. + + + For more details on potential values of this field, see documentation for + Service.ServicePort. + type: string + ref: + description: For east/west configuration, this should + point to a Service. + properties: + name: + description: Name is the user-given name of the + resource (e.g. the "billing" service). + type: string + section: + description: Section identifies which part of + the resource the condition relates to. + type: string + tenancy: + description: |- + Tenancy identifies the tenancy units (i.e. partition, namespace) in which + the resource resides. + properties: + namespace: + description: |- + Namespace further isolates resources within a partition. + https://developer.hashicorp.com/consul/docs/enterprise/namespaces + + + When using the List and WatchList endpoints, provide the wildcard value "*" + to list resources across all namespaces. + type: string + partition: + description: |- + Partition is the topmost administrative boundary within a cluster. + https://developer.hashicorp.com/consul/docs/enterprise/admin-partitions + + + When using the List and WatchList endpoints, provide the wildcard value "*" + to list resources across all partitions. + type: string + type: object + type: + description: Type identifies the resource's type. + properties: + group: + description: |- + Group describes the area of functionality to which this resource type + relates (e.g. "catalog", "authorization"). + type: string + groupVersion: + description: |- + GroupVersion is incremented when sweeping or backward-incompatible changes + are made to the group's resource types. + type: string + kind: + description: Kind identifies the specific + resource type within the group. + type: string + type: object + type: object + type: object + weight: + 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. + + + 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. + format: int32 + type: integer + type: object + type: array + type: object + type: array + type: object + status: + properties: + conditions: + description: Conditions indicate the latest available observations + of a resource's current state. + items: + description: |- + Conditions define a readiness condition for a Consul resource. + See: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties + properties: + lastTransitionTime: + description: LastTransitionTime is the 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 condition. + type: string + required: + - status + - type + type: object + type: array + lastSyncedTime: + description: LastSyncedTime is the last time the resource successfully + synced with Consul. + format: date-time + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- end }} diff --git a/kubernetes-vault/consul/templates/crd-terminatinggateways.yaml b/kubernetes-vault/consul/templates/crd-terminatinggateways.yaml new file mode 100644 index 0000000..5d78a50 --- /dev/null +++ b/kubernetes-vault/consul/templates/crd-terminatinggateways.yaml @@ -0,0 +1,148 @@ +{{- if .Values.connectInject.enabled }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: crd + name: terminatinggateways.consul.hashicorp.com +spec: + group: consul.hashicorp.com + names: + kind: TerminatingGateway + listKind: TerminatingGatewayList + plural: terminatinggateways + shortNames: + - terminating-gateway + singular: terminatinggateway + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The sync status of the resource with Consul + jsonPath: .status.conditions[?(@.type=="Synced")].status + name: Synced + type: string + - description: The last successful synced time of the resource with Consul + jsonPath: .status.lastSyncedTime + name: Last Synced + type: date + - description: The age of the resource + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: TerminatingGateway is the Schema for the terminatinggateways + 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: TerminatingGatewaySpec defines the desired state of TerminatingGateway. + properties: + services: + description: Services is a list of service names represented by the + terminating gateway. + items: + description: A LinkedService is a service represented by a terminating + gateway. + properties: + caFile: + description: |- + CAFile is the optional path to a CA certificate to use for TLS connections + from the gateway to the linked service. + type: string + certFile: + description: |- + CertFile is the optional path to a client certificate to use for TLS connections + from the gateway to the linked service. + type: string + disableAutoHostRewrite: + description: DisableAutoHostRewrite disables terminating gateways + auto host rewrite feature when set to true. + type: boolean + keyFile: + description: |- + KeyFile is the optional path to a private key to use for TLS connections + from the gateway to the linked service. + type: string + name: + description: Name is the name of the service, as defined in + Consul's catalog. + type: string + namespace: + description: The namespace the service is registered in. + type: string + sni: + description: SNI is the optional name to specify during the + TLS handshake with a linked service. + type: string + type: object + type: array + type: object + status: + properties: + conditions: + description: Conditions indicate the latest available observations + of a resource's current state. + items: + description: |- + Conditions define a readiness condition for a Consul resource. + See: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties + properties: + lastTransitionTime: + description: LastTransitionTime is the 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 condition. + type: string + required: + - status + - type + type: object + type: array + lastSyncedTime: + description: LastSyncedTime is the last time the resource successfully + synced with Consul. + format: date-time + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- end }} diff --git a/kubernetes-vault/consul/templates/crd-tlsroutes-external.yaml b/kubernetes-vault/consul/templates/crd-tlsroutes-external.yaml new file mode 100644 index 0000000..1acd1b9 --- /dev/null +++ b/kubernetes-vault/consul/templates/crd-tlsroutes-external.yaml @@ -0,0 +1,291 @@ +{{- if and .Values.connectInject.enabled .Values.connectInject.apiGateway.manageExternalCRDs }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/1538 + gateway.networking.k8s.io/bundle-version: v0.6.2 + gateway.networking.k8s.io/channel: experimental + creationTimestamp: null + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: crd + name: tlsroutes.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: TLSRoute + listKind: TLSRouteList + plural: tlsroutes + singular: tlsroute + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha2 + schema: + openAPIV3Schema: + description: "The TLSRoute resource is similar to TCPRoute, but can be configured to match against TLS-specific metadata. This allows more flexibility in matching streams for a given TLS listener. \n If you need to forward traffic to a single target for a TLS listener, you could choose to use a TCPRoute with a TLS listener." + 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 TLSRoute. + properties: + hostnames: + description: "Hostnames defines a set of SNI names that should match against the SNI attribute of TLS ClientHello message in TLS handshake. This matches the RFC 1123 definition of a hostname with 2 notable exceptions: \n 1. IPs are not allowed in SNI names per RFC 6066. 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 TLSRoute, there must be at least one intersecting hostname for the TLSRoute to be attached to the Listener. For example: \n * A Listener with `test.example.com` as the hostname matches TLSRoutes 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 TLSRoutes 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 If both the Listener and TLSRoute have specified hostnames, any TLSRoute hostnames that do not match the Listener hostname MUST be ignored. For example, if a Listener specified `*.example.com`, and the TLSRoute specified `test.example.com` and `test.example.net`, `test.example.net` must not be considered for a match. \n If both the Listener and TLSRoute have specified hostnames, and none match with the criteria above, then the TLSRoute 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. \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: + description: Rules are a list of TLS matchers and actions. + items: + description: TLSRouteRule is the configuration for a given rule. + properties: + backendRefs: + description: "BackendRefs defines the backend(s) where matching requests should be sent. If unspecified or invalid (refers to a non-existent resource or a Service with no endpoints), the rule performs no forwarding; if no filters are specified that would result in a response being sent, the underlying implementation must actively reject request attempts to this backend, by rejecting the connection or returning a 500 status code. Request rejections must respect weight; if an invalid backend is requested to have 80% of requests, then 80% of requests must be rejected instead. \n Support: Core for Kubernetes Service \n Support: Implementation-specific for any other resource \n Support for weight: Extended" + items: + description: "BackendRef defines how a Route should forward a request to a Kubernetes resource. \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." + 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 + required: + - name + type: object + maxItems: 16 + minItems: 1 + type: array + type: object + maxItems: 16 + minItems: 1 + type: array + required: + - rules + type: object + status: + description: Status defines the current state of TLSRoute. + 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 \ttype FooStatus struct{ \t // Represents the observations of a foo's current state. \t // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" \t // +patchMergeKey=type \t // +patchStrategy=merge \t // +listType=map \t // +listMapKey=type \t Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n \t // other fields \t}" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + 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: [] + storedVersions: [] +{{- end }} diff --git a/kubernetes-vault/consul/templates/crd-trafficpermissions.yaml b/kubernetes-vault/consul/templates/crd-trafficpermissions.yaml new file mode 100644 index 0000000..2a0b069 --- /dev/null +++ b/kubernetes-vault/consul/templates/crd-trafficpermissions.yaml @@ -0,0 +1,280 @@ +{{- if .Values.connectInject.enabled }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: crd + name: trafficpermissions.auth.consul.hashicorp.com +spec: + group: auth.consul.hashicorp.com + names: + kind: TrafficPermissions + listKind: TrafficPermissionsList + plural: trafficpermissions + shortNames: + - traffic-permissions + singular: trafficpermissions + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The sync status of the resource with Consul + jsonPath: .status.conditions[?(@.type=="Synced")].status + name: Synced + type: string + - description: The last successful synced time of the resource with Consul + jsonPath: .status.lastSyncedTime + name: Last Synced + type: date + - description: The age of the resource + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v2beta1 + schema: + openAPIV3Schema: + description: TrafficPermissions is the Schema for the traffic-permissions + API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: TrafficPermissions authorizes traffic between workloads in + a Consul service mesh. + properties: + action: + description: |- + Action can be either allow or deny for the entire object. It will default to allow. + Deny actions are available only in Consul Enterprise. + + + If action is allow, we will allow the connection if one of the rules in Rules matches, in other words, we will deny + all requests except for the ones that match Rules. If Consul is in default allow mode, then allow + actions have no effect without a deny permission as everything is allowed by default. + + + If action is deny, we will deny the connection if one of the rules in Rules match, in other words, + we will allow all requests except for the ones that match Rules. If Consul is default deny mode, + then deny permissions have no effect without an allow permission as everything is denied by default. + + + Action unspecified is reserved for compatibility with the addition of future actions. + enum: + - ACTION_ALLOW + - ACTION_DENY + - ACTION_UNKNOWN + format: int32 + type: string + destination: + description: |- + Destination is a configuration of the destination proxies + where these traffic permissions should apply. + properties: + identityName: + type: string + type: object + permissions: + description: Permissions is a list of permissions to match on. They + are applied using OR semantics. + items: + description: Permissions is a list of permissions to match on. + properties: + destinationRules: + description: |- + DestinationRules is a list of rules to apply for matching sources in this Permission. + These rules are specific to the request or connection that is going to the destination(s) + selected by the TrafficPermissions resource. + items: + description: DestinationRule contains rules rules to apply + to the incoming connection. + properties: + exclude: + description: Exclude contains a list of rules to exclude + when evaluating rules for the incoming connection. + items: + properties: + headers: + items: + properties: + exact: + type: string + invert: + type: boolean + name: + type: string + prefix: + type: string + present: + type: boolean + regex: + type: string + suffix: + type: string + type: object + type: array + methods: + description: Methods is the list of HTTP methods. + items: + type: string + type: array + pathExact: + type: string + pathPrefix: + type: string + pathRegex: + type: string + portNames: + description: |- + PortNames is a list of workload ports to apply this rule to. The ports specified here + must be the ports used in the connection. + items: + type: string + type: array + type: object + type: array + headers: + items: + properties: + exact: + type: string + invert: + type: boolean + name: + type: string + prefix: + type: string + present: + type: boolean + regex: + type: string + suffix: + type: string + type: object + type: array + methods: + description: |- + Methods is the list of HTTP methods. If no methods are specified, + this rule will apply to all methods. + items: + type: string + type: array + pathExact: + type: string + pathPrefix: + type: string + pathRegex: + type: string + portNames: + items: + type: string + type: array + type: object + type: array + sources: + description: Sources is a list of sources in this traffic permission. + items: + description: |- + Source represents the source identity. + To specify any of the wildcard sources, the specific fields need to be omitted. + For example, for a wildcard namespace, identity_name should be omitted. + properties: + exclude: + description: Exclude is a list of sources to exclude from + this source. + items: + description: |- + ExcludeSource is almost the same as source but it prevents the addition of + matching sources. + properties: + identityName: + type: string + namespace: + type: string + partition: + type: string + peer: + type: string + samenessGroup: + type: string + type: object + type: array + identityName: + type: string + namespace: + type: string + partition: + type: string + peer: + type: string + samenessGroup: + type: string + type: object + type: array + type: object + type: array + type: object + status: + properties: + conditions: + description: Conditions indicate the latest available observations + of a resource's current state. + items: + description: |- + Conditions define a readiness condition for a Consul resource. + See: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties + properties: + lastTransitionTime: + description: LastTransitionTime is the 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 condition. + type: string + required: + - status + - type + type: object + type: array + lastSyncedTime: + description: LastSyncedTime is the last time the resource successfully + synced with Consul. + format: date-time + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- end }} diff --git a/kubernetes-vault/consul/templates/crd-udproutes-external.yaml b/kubernetes-vault/consul/templates/crd-udproutes-external.yaml new file mode 100644 index 0000000..0661b24 --- /dev/null +++ b/kubernetes-vault/consul/templates/crd-udproutes-external.yaml @@ -0,0 +1,281 @@ +{{- if and .Values.connectInject.enabled .Values.connectInject.apiGateway.manageExternalCRDs }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/1538 + gateway.networking.k8s.io/bundle-version: v0.6.2 + gateway.networking.k8s.io/channel: experimental + creationTimestamp: null + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: crd + name: udproutes.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: UDPRoute + listKind: UDPRouteList + plural: udproutes + singular: udproute + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha2 + schema: + openAPIV3Schema: + description: UDPRoute provides a way to route UDP traffic. When combined with a Gateway listener, it can be used to forward traffic on the port specified by the listener to a set of backends specified by the UDPRoute. + 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 UDPRoute. + properties: + 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: + description: Rules are a list of UDP matchers and actions. + items: + description: UDPRouteRule is the configuration for a given rule. + properties: + backendRefs: + description: "BackendRefs defines the backend(s) where matching requests should be sent. If unspecified or invalid (refers to a non-existent resource or a Service with no endpoints), the underlying implementation MUST actively reject connection attempts to this backend. Packet drops must respect weight; if an invalid backend is requested to have 80% of the packets, then 80% of packets must be dropped instead. \n Support: Core for Kubernetes Service Support: Implementation-specific for any other resource \n Support for weight: Extended" + items: + description: "BackendRef defines how a Route should forward a request to a Kubernetes resource. \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." + 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 + required: + - name + type: object + maxItems: 16 + minItems: 1 + type: array + type: object + maxItems: 16 + minItems: 1 + type: array + required: + - rules + type: object + status: + description: Status defines the current state of UDPRoute. + 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 \ttype FooStatus struct{ \t // Represents the observations of a foo's current state. \t // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" \t // +patchMergeKey=type \t // +patchStrategy=merge \t // +listType=map \t // +listMapKey=type \t Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n \t // other fields \t}" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + 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: [] + storedVersions: [] +{{- end }} diff --git a/kubernetes-vault/consul/templates/create-federation-secret-job.yaml b/kubernetes-vault/consul/templates/create-federation-secret-job.yaml new file mode 100644 index 0000000..2092b97 --- /dev/null +++ b/kubernetes-vault/consul/templates/create-federation-secret-job.yaml @@ -0,0 +1,147 @@ +{{- if .Values.global.federation.createFederationSecret }} +{{- if not .Values.global.federation.enabled }}{{ fail "global.federation.enabled must be true when global.federation.createFederationSecret is true" }}{{ end }} +{{- if and (not .Values.global.acls.createReplicationToken) .Values.global.acls.manageSystemACLs }}{{ fail "global.acls.createReplicationToken must be true when global.acls.manageSystemACLs is true because the federation secret must include the replication token" }}{{ end }} +{{- if eq (int .Values.server.updatePartition) 0 }} +{{ template "consul.validateRequiredCloudSecretsExist" . }} +{{ template "consul.validateCloudSecretKeys" . }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ template "consul.fullname" . }}-create-federation-secret + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: create-federation-secret + {{- if .Values.global.extraLabels }} + {{- toYaml .Values.global.extraLabels | nindent 4 }} + {{- end }} + annotations: + "helm.sh/hook": post-install,post-upgrade + {{- /* Hook weight needs to be 1 so that the service account is provisioned first */}} + "helm.sh/hook-weight": "1" + "helm.sh/hook-delete-policy": hook-succeeded +spec: + template: + metadata: + name: {{ template "consul.fullname" . }}-create-federation-secret + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: create-federation-secret + {{- if .Values.global.extraLabels }} + {{- toYaml .Values.global.extraLabels | nindent 8 }} + {{- end }} + annotations: + "consul.hashicorp.com/connect-inject": "false" + "consul.hashicorp.com/mesh-inject": "false" + spec: + restartPolicy: Never + serviceAccountName: {{ template "consul.fullname" . }}-create-federation-secret + {{- if .Values.client.tolerations }} + tolerations: + {{ tpl .Values.client.tolerations . | nindent 8 | trim }} + {{- end }} + {{- if .Values.client.priorityClassName }} + priorityClassName: {{ .Values.client.priorityClassName | quote }} + {{- end }} + {{- if .Values.client.nodeSelector }} + nodeSelector: + {{ tpl .Values.client.nodeSelector . | indent 8 | trim }} + {{- end }} + volumes: + {{- /* We can assume tls is enabled because there is a check in server-statefulset + that requires tls to be enabled if federation is enabled. */}} + - name: consul-ca-cert + secret: + {{- if .Values.global.tls.caCert.secretName }} + secretName: {{ .Values.global.tls.caCert.secretName }} + {{- else }} + secretName: {{ template "consul.fullname" . }}-ca-cert + {{- end }} + items: + - key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }} + path: tls.crt + - name: consul-ca-key + secret: + {{- if .Values.global.tls.caKey.secretName }} + secretName: {{ .Values.global.tls.caKey.secretName }} + {{- else }} + secretName: {{ template "consul.fullname" . }}-ca-key + {{- end }} + items: + - key: {{ default "tls.key" .Values.global.tls.caKey.secretKey }} + path: tls.key + {{- if (and .Values.global.gossipEncryption.secretName .Values.global.gossipEncryption.secretKey) }} + - name: gossip-encryption-key + secret: + secretName: {{ .Values.global.gossipEncryption.secretName }} + items: + - key: {{ .Values.global.gossipEncryption.secretKey }} + path: gossip.key + {{- else if .Values.global.gossipEncryption.autoGenerate }} + - name: gossip-encryption-key + secret: + secretName: {{ template "consul.fullname" . }}-gossip-encryption-key + items: + - key: key + path: gossip.key + {{- end }} + + containers: + - name: create-federation-secret + image: "{{ .Values.global.imageK8S }}" + {{ template "consul.imagePullPolicy" . }} + {{- include "consul.restrictedSecurityContext" . | nindent 10 }} + env: + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: CONSUL_HTTP_ADDR + value: "https://{{ template "consul.fullname" . }}-server.{{ .Release.Namespace }}.svc:8501" + - name: CONSUL_CACERT + value: /consul/tls/ca/tls.crt + volumeMounts: + - name: consul-ca-cert + mountPath: /consul/tls/ca + readOnly: true + - name: consul-ca-key + mountPath: /consul/tls/server/ca + readOnly: true + {{- if (or .Values.global.gossipEncryption.autoGenerate (and .Values.global.gossipEncryption.secretName .Values.global.gossipEncryption.secretKey)) }} + - name: gossip-encryption-key + mountPath: /consul/gossip + readOnly: true + {{- end }} + command: + - "/bin/sh" + - "-ec" + - | + exec consul-k8s-control-plane create-federation-secret \ + -log-level={{ default .Values.global.logLevel .Values.global.federation.logLevel }} \ + -log-json={{ .Values.global.logJSON }} \ + {{- if (or .Values.global.gossipEncryption.autoGenerate (and .Values.global.gossipEncryption.secretName .Values.global.gossipEncryption.secretKey)) }} + -gossip-key-file=/consul/gossip/gossip.key \ + {{- end }} + {{- if .Values.global.acls.createReplicationToken }} + -export-replication-token=true \ + {{- end }} + -mesh-gateway-service-name={{ .Values.meshGateway.consulServiceName }} \ + -k8s-namespace="${NAMESPACE}" \ + -resource-prefix="{{ template "consul.fullname" . }}" \ + -server-ca-cert-file=/consul/tls/ca/tls.crt \ + -server-ca-key-file=/consul/tls/server/ca/tls.key \ + -consul-api-timeout={{ .Values.global.consulAPITimeout }} + resources: + requests: + memory: "50Mi" + cpu: "50m" + limits: + memory: "50Mi" + cpu: "50m" +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/create-federation-secret-podsecuritypolicy.yaml b/kubernetes-vault/consul/templates/create-federation-secret-podsecuritypolicy.yaml new file mode 100644 index 0000000..8217311 --- /dev/null +++ b/kubernetes-vault/consul/templates/create-federation-secret-podsecuritypolicy.yaml @@ -0,0 +1,42 @@ +{{- if .Values.global.enablePodSecurityPolicies }} +{{- if .Values.global.federation.createFederationSecret }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "consul.fullname" . }}-create-federation-secret + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: create-federation-secret + annotations: + "helm.sh/hook": post-install,post-upgrade + "helm.sh/hook-delete-policy": hook-succeeded,before-hook-creation +spec: + privileged: false + # Required to prevent escalations to root. + allowPrivilegeEscalation: false + # This is redundant with non-root + disallow privilege escalation, + # but we can provide it for defense in depth. + requiredDropCapabilities: + - ALL + # Allow core volume types. + volumes: + - 'secret' + - 'emptyDir' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' + readOnlyRootFilesystem: false +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/create-federation-secret-role.yaml b/kubernetes-vault/consul/templates/create-federation-secret-role.yaml new file mode 100644 index 0000000..086932a --- /dev/null +++ b/kubernetes-vault/consul/templates/create-federation-secret-role.yaml @@ -0,0 +1,49 @@ +{{- if .Values.global.federation.createFederationSecret }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "consul.fullname" . }}-create-federation-secret + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: create-federation-secret + annotations: + "helm.sh/hook": post-install,post-upgrade + "helm.sh/hook-delete-policy": hook-succeeded,before-hook-creation +rules: + {{/* Must have separate rule for create secret permissions vs update because + can't set resourceNames for create (https://github.com/kubernetes/kubernetes/issues/80295) */}} + - apiGroups: [""] + resources: + - secrets + verbs: + - create + - apiGroups: [""] + resources: + - secrets + resourceNames: + - {{ template "consul.fullname" . }}-federation + verbs: + - update + {{- if .Values.global.acls.manageSystemACLs }} + - apiGroups: [""] + resources: + - secrets + resourceNames: + - {{ template "consul.fullname" . }}-acl-replication-acl-token + verbs: + - get + {{- end }} + {{- if .Values.global.enablePodSecurityPolicies }} + - apiGroups: ["policy"] + resources: + - podsecuritypolicies + verbs: + - use + resourceNames: + - {{ template "consul.fullname" . }}-create-federation-secret + {{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/create-federation-secret-rolebinding.yaml b/kubernetes-vault/consul/templates/create-federation-secret-rolebinding.yaml new file mode 100644 index 0000000..3db8e7c --- /dev/null +++ b/kubernetes-vault/consul/templates/create-federation-secret-rolebinding.yaml @@ -0,0 +1,23 @@ +{{- if .Values.global.federation.createFederationSecret }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "consul.fullname" . }}-create-federation-secret + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: create-federation-secret + annotations: + "helm.sh/hook": post-install,post-upgrade + "helm.sh/hook-delete-policy": hook-succeeded,before-hook-creation +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "consul.fullname" . }}-create-federation-secret +subjects: +- kind: ServiceAccount + name: {{ template "consul.fullname" . }}-create-federation-secret +{{- end }} diff --git a/kubernetes-vault/consul/templates/create-federation-secret-serviceaccount.yaml b/kubernetes-vault/consul/templates/create-federation-secret-serviceaccount.yaml new file mode 100644 index 0000000..e398ec6 --- /dev/null +++ b/kubernetes-vault/consul/templates/create-federation-secret-serviceaccount.yaml @@ -0,0 +1,22 @@ +{{- if .Values.global.federation.createFederationSecret }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "consul.fullname" . }}-create-federation-secret + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: create-federation-secret + annotations: + "helm.sh/hook": post-install,post-upgrade + "helm.sh/hook-delete-policy": hook-succeeded,before-hook-creation +{{- with .Values.global.imagePullSecrets }} +imagePullSecrets: +{{- range . }} + - name: {{ .name }} +{{- end }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/datadog-agent-role.yaml b/kubernetes-vault/consul/templates/datadog-agent-role.yaml new file mode 100644 index 0000000..191e643 --- /dev/null +++ b/kubernetes-vault/consul/templates/datadog-agent-role.yaml @@ -0,0 +1,38 @@ +{{- if .Values.global.metrics.datadog.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "consul.fullname" . }}-datadog-metrics + namespace: {{ .Release.Namespace }} + labels: + app: datadog + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: agent +{{- if (or (and .Values.global.openshift.enabled .Values.server.exposeGossipAndRPCPorts) .Values.global.enablePodSecurityPolicies) }} +{{- if .Values.global.enablePodSecurityPolicies }} +rules: + - apiGroups: ["policy"] + resources: ["podsecuritypolicies"] + resourceNames: + - {{ template "consul.fullname" . }}-datadog-metrics + verbs: + - use +{{- end }} +{{- if (and .Values.global.openshift.enabled .Values.server.exposeGossipAndRPCPorts ) }} + - apiGroups: ["security.openshift.io"] + resources: ["securitycontextconstraints"] + resourceNames: + - {{ template "consul.fullname" . }}-datadog-metrics + verbs: + - use +{{- end }} +{{- else}} +rules: + - apiGroups: [ "" ] + resources: [ "secrets" ] + resourceNames: + - {{ .Release.Namespace }}-datadog-agent-metrics-acl-token + verbs: [ "get", "watch", "list" ] +{{- end }} +{{- end }} \ No newline at end of file diff --git a/kubernetes-vault/consul/templates/datadog-agent-rolebinding.yaml b/kubernetes-vault/consul/templates/datadog-agent-rolebinding.yaml new file mode 100644 index 0000000..5fc3fdf --- /dev/null +++ b/kubernetes-vault/consul/templates/datadog-agent-rolebinding.yaml @@ -0,0 +1,26 @@ +{{- if .Values.global.metrics.datadog.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "consul.fullname" . }}-datadog-metrics + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: agent +subjects: + - kind: ServiceAccount + apiGroup: "" + name: datadog-agent + namespace: datadog + - kind: ServiceAccount + apiGroup: "" + name: datadog-cluster-agent + namespace: datadog +roleRef: + kind: Role + name: {{ template "consul.fullname" . }}-datadog-metrics + apiGroup: "" +{{- end }} \ No newline at end of file diff --git a/kubernetes-vault/consul/templates/dns-service.yaml b/kubernetes-vault/consul/templates/dns-service.yaml new file mode 100644 index 0000000..5bb446b --- /dev/null +++ b/kubernetes-vault/consul/templates/dns-service.yaml @@ -0,0 +1,41 @@ +{{- if (or (and (ne (.Values.dns.enabled | toString) "-") .Values.dns.enabled) (and (eq (.Values.dns.enabled | toString) "-") .Values.connectInject.transparentProxy.defaultEnabled)) }} +# Service for Consul DNS. +apiVersion: v1 +kind: Service +metadata: + name: {{ template "consul.fullname" . }}-dns + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: dns + {{- if .Values.dns.annotations }} + annotations: + {{ tpl .Values.dns.annotations . | nindent 4 | trim }} + {{- end }} +spec: +{{- if .Values.dns.type }} + type: {{ .Values.dns.type }} +{{- end }} +{{- if .Values.dns.clusterIP }} + clusterIP: {{ .Values.dns.clusterIP }} +{{- end }} + ports: + - name: dns-tcp + port: 53 + protocol: "TCP" + targetPort: dns-tcp + - name: dns-udp + port: 53 + protocol: "UDP" + targetPort: dns-udp + selector: + app: {{ template "consul.name" . }} + release: "{{ .Release.Name }}" + hasDNS: "true" + {{- if .Values.dns.additionalSpec }} + {{ tpl .Values.dns.additionalSpec . | nindent 2 | trim }} + {{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/enterprise-license-job.yaml b/kubernetes-vault/consul/templates/enterprise-license-job.yaml new file mode 100644 index 0000000..9dd0281 --- /dev/null +++ b/kubernetes-vault/consul/templates/enterprise-license-job.yaml @@ -0,0 +1,147 @@ +{{- if .Values.server.enterpriseLicense }}{{ fail "server.enterpriseLicense has been moved to global.enterpriseLicense" }}{{ end -}} +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if (and .Values.global.enterpriseLicense.secretName .Values.global.enterpriseLicense.secretKey (not .Values.global.enterpriseLicense.enableLicenseAutoload)) }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ template "consul.fullname" . }}-enterprise-license + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/managed-by: {{.Release.Service | quote }} + app.kubernetes.io/instance: {{.Release.Name | quote }} + helm.sh/chart: "{{.Chart.Name}}-{{.Chart.Version}}" + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: license + {{- if .Values.global.extraLabels }} + {{- toYaml .Values.global.extraLabels | nindent 4 }} + {{- end }} + annotations: + "helm.sh/hook": post-install,post-upgrade + "helm.sh/hook-weight": "100" + "helm.sh/hook-delete-policy": hook-succeeded +spec: + template: + metadata: + name: {{ template "consul.fullname" . }}-license + labels: + app.kubernetes.io/managed-by: {{.Release.Service | quote }} + app.kubernetes.io/instance: {{.Release.Name | quote }} + helm.sh/chart: "{{.Chart.Name}}-{{.Chart.Version}}" + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: license + {{- if .Values.global.extraLabels }} + {{- toYaml .Values.global.extraLabels | nindent 8 }} + {{- end }} + annotations: + "consul.hashicorp.com/connect-inject": "false" + "consul.hashicorp.com/mesh-inject": "false" + spec: + restartPolicy: Never + serviceAccountName: {{ template "consul.fullname" . }}-enterprise-license + {{- if .Values.global.tls.enabled }} + volumes: + - name: consul-ca-cert + secret: + {{- if .Values.global.tls.caCert.secretName }} + secretName: {{ .Values.global.tls.caCert.secretName }} + {{- else }} + secretName: {{ template "consul.fullname" . }}-ca-cert + {{- end }} + items: + - key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }} + path: tls.crt + {{- end }} + containers: + - name: apply-enterprise-license + image: "{{ default .Values.global.image .Values.server.image }}" + {{ template "consul.imagePullPolicy" . }} + env: + - name: ENTERPRISE_LICENSE + {{- if .Values.global.secretsBackend.vault.enabled }} + value: /vault/secrets/enterpriselicense.txt + {{- else }} + valueFrom: + secretKeyRef: + name: {{ .Values.global.enterpriseLicense.secretName }} + key: {{ .Values.global.enterpriseLicense.secretKey }} + {{- end }} + - name: CONSUL_HTTP_ADDR + {{- if .Values.global.tls.enabled }} + value: https://{{ template "consul.fullname" . }}-server:8501 + {{- else }} + value: http://{{ template "consul.fullname" . }}-server:8500 + {{- end }} + {{- if .Values.global.tls.enabled }} + - name: CONSUL_CACERT + value: /consul/tls/ca/tls.crt + {{- end}} + {{- if .Values.global.acls.manageSystemACLs }} + - name: CONSUL_HTTP_TOKEN + valueFrom: + secretKeyRef: + name: "{{ template "consul.fullname" . }}-enterprise-license-acl-token" + key: "token" + {{- end}} + command: + - "/bin/sh" + - "-c" + - | + # Create a script that we can execute with the timeout command. + mkdir -p /tmp/scripts/ + cat > /tmp/scripts/apply-license.sh << 'EOF' + #!/bin/sh + while true; do + echo "Applying license..." + if consul license put "${ENTERPRISE_LICENSE}" 2>&1; then + echo "License applied successfully" + break + fi + echo "Retrying in 2s..." + sleep 2 + done + EOF + chmod +x /tmp/scripts/apply-license.sh + + # Time out after 20 minutes. Use || to support new timeout versions that don't accept -t + timeout -t 1200 /tmp/scripts/apply-license.sh 2> /dev/null || timeout 1200 /tmp/scripts/apply-license.sh 2> /dev/null + {{- if .Values.global.tls.enabled }} + volumeMounts: + - name: consul-ca-cert + mountPath: /consul/tls/ca + readOnly: true + {{- end }} + resources: + requests: + memory: "50Mi" + cpu: "50m" + limits: + memory: "50Mi" + cpu: "50m" + {{- if .Values.global.acls.manageSystemACLs }} + initContainers: + - name: ent-license-acl-init + image: {{ .Values.global.imageK8S }} + {{ template "consul.imagePullPolicy" . }} + command: + - "/bin/sh" + - "-ec" + - | + exec consul-k8s-control-plane acl-init \ + -secret-name="{{ template "consul.fullname" . }}-enterprise-license-acl-token" \ + -k8s-namespace={{ .Release.Namespace }} \ + -consul-api-timeout={{ .Values.global.consulAPITimeout }} + resources: + requests: + memory: "25Mi" + cpu: "50m" + limits: + memory: "25Mi" + cpu: "50m" + {{- end }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/enterprise-license-podsecuritypolicy.yaml b/kubernetes-vault/consul/templates/enterprise-license-podsecuritypolicy.yaml new file mode 100644 index 0000000..cf96367 --- /dev/null +++ b/kubernetes-vault/consul/templates/enterprise-license-podsecuritypolicy.yaml @@ -0,0 +1,39 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if (and .Values.global.enterpriseLicense.secretName .Values.global.enterpriseLicense.secretKey (not .Values.global.enterpriseLicense.enableLicenseAutoload)) }} +{{- if .Values.global.enablePodSecurityPolicies }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "consul.fullname" . }}-enterprise-license + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: license +spec: + privileged: false + # Allow core volume types. + volumes: + - 'secret' + allowPrivilegeEscalation: false + # This is redundant with non-root + disallow privilege escalation, + # but we can provide it for defense in depth. + requiredDropCapabilities: + - ALL + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' + readOnlyRootFilesystem: false +{{- end }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/enterprise-license-role.yaml b/kubernetes-vault/consul/templates/enterprise-license-role.yaml new file mode 100644 index 0000000..6a1b7fd --- /dev/null +++ b/kubernetes-vault/consul/templates/enterprise-license-role.yaml @@ -0,0 +1,37 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if (and .Values.global.enterpriseLicense.secretName .Values.global.enterpriseLicense.secretKey (not .Values.global.enterpriseLicense.enableLicenseAutoload)) }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "consul.fullname" . }}-enterprise-license + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: license +{{- if or .Values.global.acls.manageSystemACLs .Values.global.enablePodSecurityPolicies }} +rules: +{{- if .Values.global.acls.manageSystemACLs }} + - apiGroups: [""] + resources: + - secrets + resourceNames: + - {{ template "consul.fullname" . }}-enterprise-license-acl-token + verbs: + - get +{{- end }} +{{- if .Values.global.enablePodSecurityPolicies }} + - apiGroups: ["policy"] + resources: ["podsecuritypolicies"] + resourceNames: + - {{ template "consul.fullname" . }}-enterprise-license + verbs: + - use +{{- end }} +{{- else }} +rules: [] +{{- end }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/enterprise-license-rolebinding.yaml b/kubernetes-vault/consul/templates/enterprise-license-rolebinding.yaml new file mode 100644 index 0000000..a21118b --- /dev/null +++ b/kubernetes-vault/consul/templates/enterprise-license-rolebinding.yaml @@ -0,0 +1,22 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if (and .Values.global.enterpriseLicense.secretName .Values.global.enterpriseLicense.secretKey (not .Values.global.enterpriseLicense.enableLicenseAutoload)) }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "consul.fullname" . }}-enterprise-license + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: license +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "consul.fullname" . }}-enterprise-license +subjects: + - kind: ServiceAccount + name: {{ template "consul.fullname" . }}-enterprise-license +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/enterprise-license-serviceaccount.yaml b/kubernetes-vault/consul/templates/enterprise-license-serviceaccount.yaml new file mode 100644 index 0000000..31c9da8 --- /dev/null +++ b/kubernetes-vault/consul/templates/enterprise-license-serviceaccount.yaml @@ -0,0 +1,21 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if (and .Values.global.enterpriseLicense.secretName .Values.global.enterpriseLicense.secretKey (not .Values.global.enterpriseLicense.enableLicenseAutoload)) }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "consul.fullname" . }}-enterprise-license + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: license +{{- with .Values.global.imagePullSecrets }} +imagePullSecrets: +{{- range . }} + - name: {{ .name }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/expose-servers-service.yaml b/kubernetes-vault/consul/templates/expose-servers-service.yaml new file mode 100644 index 0000000..d86cec9 --- /dev/null +++ b/kubernetes-vault/consul/templates/expose-servers-service.yaml @@ -0,0 +1,63 @@ +{{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} +{{- $serverExposeServiceEnabled := (or (and (ne (.Values.server.exposeService.enabled | toString) "-") .Values.server.exposeService.enabled) (and (eq (.Values.server.exposeService.enabled | toString) "-") .Values.global.adminPartitions.enabled)) -}} +{{- if (and $serverEnabled $serverExposeServiceEnabled) }} + +# Service with an external IP to reach Consul servers. +# Used for exposing gRPC port for peering and ports for client partitions to discover servers. +apiVersion: v1 +kind: Service +metadata: + name: {{ template "consul.fullname" . }}-expose-servers + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: server + annotations: + {{- if .Values.server.exposeService.annotations }} + {{ tpl .Values.server.exposeService.annotations . | nindent 4 | trim }} + {{- end }} +spec: + type: "{{ .Values.server.exposeService.type }}" + ports: + {{- if (or (not .Values.global.tls.enabled) (not .Values.global.tls.httpsOnly)) }} + - name: http + port: 8500 + targetPort: 8500 + {{ if (and (eq .Values.server.exposeService.type "NodePort") .Values.server.exposeService.nodePort.http) }} + nodePort: {{ .Values.server.exposeService.nodePort.http }} + {{- end }} + {{- end }} + {{- if .Values.global.tls.enabled }} + - name: https + port: 8501 + targetPort: 8501 + {{ if (and (eq .Values.server.exposeService.type "NodePort") .Values.server.exposeService.nodePort.https) }} + nodePort: {{ .Values.server.exposeService.nodePort.https }} + {{- end }} + {{- end }} + - name: serflan + port: 8301 + targetPort: 8301 + {{ if (and (eq .Values.server.exposeService.type "NodePort") .Values.server.exposeService.nodePort.serf) }} + nodePort: {{ .Values.server.exposeService.nodePort.serf }} + {{- end }} + - name: rpc + port: 8300 + targetPort: 8300 + {{ if (and (eq .Values.server.exposeService.type "NodePort") .Values.server.exposeService.nodePort.rpc) }} + nodePort: {{ .Values.server.exposeService.nodePort.rpc }} + {{- end }} + - name: grpc + port: 8502 + targetPort: 8502 + {{ if (and (eq .Values.server.exposeService.type "NodePort") .Values.server.exposeService.nodePort.grpc) }} + nodePort: {{ .Values.server.exposeService.nodePort.grpc }} + {{- end }} + selector: + app: {{ template "consul.name" . }} + release: "{{ .Release.Name }}" + component: server +{{- end }} diff --git a/kubernetes-vault/consul/templates/gateway-cleanup-clusterrole.yaml b/kubernetes-vault/consul/templates/gateway-cleanup-clusterrole.yaml new file mode 100644 index 0000000..5518bfc --- /dev/null +++ b/kubernetes-vault/consul/templates/gateway-cleanup-clusterrole.yaml @@ -0,0 +1,44 @@ +{{- if .Values.connectInject.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "consul.fullname" . }}-gateway-cleanup + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: gateway-cleanup +rules: + - apiGroups: + - consul.hashicorp.com + resources: + - gatewayclassconfigs + verbs: + - get + - delete + - apiGroups: + - gateway.networking.k8s.io + resources: + - gatewayclasses + verbs: + - get + - delete + - apiGroups: + - mesh.consul.hashicorp.com + resources: + - gatewayclassconfigs + - gatewayclasses + - meshgateways + verbs: + - get + - delete +{{- if .Values.global.enablePodSecurityPolicies }} + - apiGroups: ["policy"] + resources: ["podsecuritypolicies"] + resourceNames: + - {{ template "consul.fullname" . }}-gateway-cleanup + verbs: + - use +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/gateway-cleanup-clusterrolebinding.yaml b/kubernetes-vault/consul/templates/gateway-cleanup-clusterrolebinding.yaml new file mode 100644 index 0000000..9235f32 --- /dev/null +++ b/kubernetes-vault/consul/templates/gateway-cleanup-clusterrolebinding.yaml @@ -0,0 +1,20 @@ +{{- if .Values.connectInject.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "consul.fullname" . }}-gateway-cleanup + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: gateway-cleanup +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "consul.fullname" . }}-gateway-cleanup +subjects: + - kind: ServiceAccount + name: {{ template "consul.fullname" . }}-gateway-cleanup + namespace: {{ .Release.Namespace }} +{{- end }} \ No newline at end of file diff --git a/kubernetes-vault/consul/templates/gateway-cleanup-job.yaml b/kubernetes-vault/consul/templates/gateway-cleanup-job.yaml new file mode 100644 index 0000000..0d38f6e --- /dev/null +++ b/kubernetes-vault/consul/templates/gateway-cleanup-job.yaml @@ -0,0 +1,68 @@ +{{- if .Values.connectInject.enabled }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ template "consul.fullname" . }}-gateway-cleanup + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: gateway-cleanup + {{- if .Values.global.extraLabels }} + {{- toYaml .Values.global.extraLabels | nindent 4 }} + {{- end }} + annotations: + "helm.sh/hook": pre-delete + "helm.sh/hook-weight": "0" + "helm.sh/hook-delete-policy": hook-succeeded,hook-failed +spec: + template: + metadata: + name: {{ template "consul.fullname" . }}-gateway-cleanup + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: gateway-cleanup + {{- if .Values.global.extraLabels }} + {{- toYaml .Values.global.extraLabels | nindent 8 }} + {{- end }} + annotations: + "consul.hashicorp.com/connect-inject": "false" + "consul.hashicorp.com/mesh-inject": "false" + spec: + restartPolicy: Never + serviceAccountName: {{ template "consul.fullname" . }}-gateway-cleanup + containers: + - name: gateway-cleanup + image: {{ .Values.global.imageK8S }} + {{ template "consul.imagePullPolicy" . }} + {{- include "consul.restrictedSecurityContext" . | nindent 10 }} + command: + - consul-k8s-control-plane + args: + - gateway-cleanup + - -gateway-class-name=consul + - -gateway-class-config-name=consul-api-gateway + resources: + requests: + memory: "50Mi" + cpu: "50m" + limits: + memory: "50Mi" + cpu: "50m" + volumeMounts: + - name: config + mountPath: /consul/config + readOnly: true + {{- if .Values.global.acls.tolerations }} + tolerations: + {{ tpl .Values.global.acls.tolerations . | indent 8 | trim }} + {{- end }} + volumes: + - name: config + configMap: + name: {{ template "consul.fullname" . }}-gateway-resources-config +{{- end }} diff --git a/kubernetes-vault/consul/templates/gateway-cleanup-podsecuritypolicy.yaml b/kubernetes-vault/consul/templates/gateway-cleanup-podsecuritypolicy.yaml new file mode 100644 index 0000000..ffbad13 --- /dev/null +++ b/kubernetes-vault/consul/templates/gateway-cleanup-podsecuritypolicy.yaml @@ -0,0 +1,32 @@ +{{- if (and .Values.connectInject.enabled .Values.global.enablePodSecurityPolicies)}} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "consul.fullname" . }}-gateway-cleanup + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: gateway-cleanup +spec: + privileged: false + allowPrivilegeEscalation: false + # This is redundant with non-root + disallow privilege escalation, + # but we can provide it for defense in depth. + requiredDropCapabilities: + - ALL + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' + readOnlyRootFilesystem: false +{{- end }} diff --git a/kubernetes-vault/consul/templates/gateway-cleanup-serviceaccount.yaml b/kubernetes-vault/consul/templates/gateway-cleanup-serviceaccount.yaml new file mode 100644 index 0000000..52c340f --- /dev/null +++ b/kubernetes-vault/consul/templates/gateway-cleanup-serviceaccount.yaml @@ -0,0 +1,19 @@ +{{- if .Values.connectInject.enabled }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "consul.fullname" . }}-gateway-cleanup + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: gateway-cleanup +{{- with .Values.global.imagePullSecrets }} +imagePullSecrets: +{{- range . }} + - name: {{ .name }} +{{- end }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/gateway-resources-clusterrole.yaml b/kubernetes-vault/consul/templates/gateway-resources-clusterrole.yaml new file mode 100644 index 0000000..ad7082f --- /dev/null +++ b/kubernetes-vault/consul/templates/gateway-resources-clusterrole.yaml @@ -0,0 +1,47 @@ +{{- if .Values.connectInject.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "consul.fullname" . }}-gateway-resources + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: gateway-resources +rules: + - apiGroups: + - mesh.consul.hashicorp.com + resources: + - meshgateways + verbs: + - get + - update + - create + - apiGroups: + - consul.hashicorp.com + - mesh.consul.hashicorp.com + resources: + - gatewayclassconfigs + verbs: + - get + - update + - create + - apiGroups: + - gateway.networking.k8s.io + - mesh.consul.hashicorp.com + resources: + - gatewayclasses + verbs: + - get + - update + - create +{{- if .Values.global.enablePodSecurityPolicies }} + - apiGroups: ["policy"] + resources: ["podsecuritypolicies"] + resourceNames: + - {{ template "consul.fullname" . }}-gateway-resources + verbs: + - use +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/gateway-resources-clusterrolebinding.yaml b/kubernetes-vault/consul/templates/gateway-resources-clusterrolebinding.yaml new file mode 100644 index 0000000..921df23 --- /dev/null +++ b/kubernetes-vault/consul/templates/gateway-resources-clusterrolebinding.yaml @@ -0,0 +1,20 @@ +{{- if .Values.connectInject.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "consul.fullname" . }}-gateway-resources + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: gateway-resources +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "consul.fullname" . }}-gateway-resources +subjects: + - kind: ServiceAccount + name: {{ template "consul.fullname" . }}-gateway-resources + namespace: {{ .Release.Namespace }} +{{- end }} \ No newline at end of file diff --git a/kubernetes-vault/consul/templates/gateway-resources-configmap.yaml b/kubernetes-vault/consul/templates/gateway-resources-configmap.yaml new file mode 100644 index 0000000..d00f9b3 --- /dev/null +++ b/kubernetes-vault/consul/templates/gateway-resources-configmap.yaml @@ -0,0 +1,195 @@ +{{- if .Values.connectInject.enabled }} + +# Validation +# For meshGateway.wanAddress, static must be set if source is "Static" +{{if (and (eq .Values.meshGateway.wanAddress.source "Static") (eq .Values.meshGateway.wanAddress.static ""))}}{{fail ".meshGateway.wanAddress.static must be set to a value if .meshGateway.wanAddress.source is Static"}}{{ end }} + +# Configuration of Gateway Resources Job which creates managed Gateway configuration. +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "consul.fullname" . }}-gateway-resources-config + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: gateway-resources +data: + {{- if .Values.connectInject.apiGateway.managedGatewayClass.resources }} + resources.json: | + {{ toJson .Values.connectInject.apiGateway.managedGatewayClass.resources }} + {{- end }} + {{- if and (mustHas "resource-apis" .Values.global.experiments) (or .Values.meshGateway.enabled .Values.connectInject.apiGateway.managedGatewayClass) }} + config.yaml: | + gatewayClassConfigs: + {{- if .Values.meshGateway.enabled }} + - apiVersion: mesh.consul.hashicorp.com/v2beta1 + metadata: + name: consul-mesh-gateway + kind: GatewayClassConfig + spec: + labels: + set: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: mesh-gateway + deployment: + {{- if .Values.meshGateway.priorityClassName }} + priorityClassName: {{ .Values.meshGateway.priorityClassName | quote }} + {{- end }} + {{- if .Values.meshGateway.affinity }} + affinity: {{ toJson (default "{}" .Values.meshGateway.affinity) }} + {{- end }} + {{- if .Values.meshGateway.annotations }} + annotations: + set: {{ toJson .Values.meshGateway.annotations }} + {{- end }} + {{- if .Values.global.extraLabels }} + labels: + set: {{ toJson .Values.global.extraLabels }} + {{- end }} + container: + consul: + logging: + level: {{ default .Values.global.logLevel .Values.meshGateway.logLevel }} + portModifier: {{ sub .Values.meshGateway.containerPort .Values.meshGateway.service.port }} + {{- if .Values.meshGateway.hostPort }} + hostPort: {{ .Values.meshGateway.hostPort }} + {{- end }} + resources: {{ toJson .Values.meshGateway.resources }} + initContainer: + consul: + logging: + level: {{ default .Values.global.logLevel .Values.meshGateway.logLevel }} + resources: {{ toJson .Values.meshGateway.initServiceInitContainer.resources }} + {{- with .Values.meshGateway.nodeSelector }} + nodeSelector: {{ fromYaml . | toJson }} + {{- end }} + {{- with .Values.meshGateway.hostNetwork }} + hostNetwork: {{ . }} + {{- end }} + {{- with .Values.meshGateway.dnsPolicy }} + dnsPolicy: {{ . }} + {{- end }} + {{- with .Values.meshGateway.topologySpreadConstraints }} + topologySpreadConstraints: + {{ fromYamlArray . | toJson }} + {{- end }} + {{- if .Values.meshGateway.affinity }} + affinity: + {{ tpl .Values.meshGateway.affinity . | nindent 16 | trim }} + {{- end }} + replicas: + default: {{ .Values.meshGateway.replicas }} + min: {{ .Values.meshGateway.replicas }} + max: {{ .Values.meshGateway.replicas }} + {{- if .Values.meshGateway.tolerations }} + tolerations: + {{ fromYamlArray .Values.meshGateway.tolerations | toJson }} + {{- end }} + service: + {{- if .Values.meshGateway.service.annotations }} + annotations: + set: {{ toJson .Values.meshGateway.service.annotations }} + {{- end }} + type: {{ .Values.meshGateway.service.type }} + {{- if .Values.meshGateway.serviceAccount.annotations }} + serviceAccount: + annotations: + set: {{ toJson .Values.meshGateway.serviceAccount.annotations }} + {{- end }} + {{- end }} + {{- if .Values.connectInject.apiGateway.managedGatewayClass }} + - apiVersion: mesh.consul.hashicorp.com/v2beta1 + metadata: + name: consul-api-gateway + kind: GatewayClassConfig + spec: + labels: + set: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: api-gateway + {{- if .Values.connectInject.apiGateway.managedGatewayClass.copyAnnotations }} + {{- if .Values.connectInject.apiGateway.managedGatewayClass.copyAnnotations.service }} + annotations: + service: + {{ fromYamlArray .Values.connectInject.apiGateway.managedGatewayClass.copyAnnotations.service.annotations | toYaml }} + {{- end}} + {{- end}} + deployment: + {{- if .Values.connectInject.apiGateway.managedGatewayClass.nodeSelector }} + nodeSelector: + {{ fromYamlArray .Values.connectInject.apiGateway.managedGatewayClass.nodeSelector | toYaml }} + {{- end }} + initContainer: + {{- if .Values.connectInject.apiGateway.managedGatewayClass.mapPrivilegedContainerPorts }} + portModifier: {{ .Values.connectInject.apiGateway.managedGatewayClass.mapPrivilegedContainerPorts }} + {{- end }} + consul: + logging: + level: {{ .Values.global.logLevel }} + container: + {{- if .Values.connectInject.apiGateway.managedGatewayClass.mapPrivilegedContainerPorts }} + portModifier: {{ .Values.connectInject.apiGateway.managedGatewayClass.mapPrivilegedContainerPorts }} + {{- end }} + consul: + logging: + level: {{ .Values.global.logLevel }} + replicas: + default: {{ .Values.connectInject.apiGateway.managedGatewayClass.deployment.defaultInstances }} + min: {{ .Values.connectInject.apiGateway.managedGatewayClass.deployment.minInstances }} + max: {{ .Values.connectInject.apiGateway.managedGatewayClass.deployment.maxInstances }} + {{- if .Values.connectInject.apiGateway.managedGatewayClass.tolerations }} + tolerations: + {{ fromYamlArray .Values.connectInject.apiGateway.managedGatewayClass.tolerations | toYaml }} + {{- end }} + {{- if .Values.connectInject.apiGateway.managedGatewayClass.service }} + service: + annotations: + set: {{ toYaml .Values.connectInject.apiGateway.managedGatewayClass.service.annotations }} + {{- end }} + type: {{ .Values.connectInject.apiGateway.managedGatewayClass.serviceType }} + {{- if .Values.connectInject.apiGateway.managedGatewayClass.serviceAccount }} + serviceAccount: + annotations: + set: {{ toYaml .Values.connectInject.apiGateway.managedGatewayClass.serviceAccount.annotations }} + {{- end }} + {{- end }} + {{- if .Values.meshGateway.enabled }} + meshGateways: + - apiVersion: mesh.consul.hashicorp.com/v2beta1 + kind: MeshGateway + metadata: + name: mesh-gateway + namespace: {{ .Release.Namespace }} + annotations: + "consul.hashicorp.com/gateway-wan-address-source": {{ .Values.meshGateway.wanAddress.source | quote }} + "consul.hashicorp.com/gateway-wan-address-static": {{ .Values.meshGateway.wanAddress.static | quote }} + {{- if eq .Values.meshGateway.wanAddress.source "Service" }} + {{- if eq .Values.meshGateway.service.type "NodePort" }} + "consul.hashicorp.com/gateway-wan-port": {{ .Values.meshGateway.service.nodePort | quote }} + {{- else }} + "consul.hashicorp.com/gateway-wan-port": {{ .Values.meshGateway.service.port | quote }} + {{- end }} + {{- else }} + "consul.hashicorp.com/gateway-wan-port": {{ .Values.meshGateway.wanAddress.port | quote }} + {{- end }} + spec: + gatewayClassName: consul-mesh-gateway + listeners: + - name: "wan" + port: {{ .Values.meshGateway.service.port }} + protocol: "TCP" + workloads: + prefixes: + - "mesh-gateway" + {{- end }} + {{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/gateway-resources-job.yaml b/kubernetes-vault/consul/templates/gateway-resources-job.yaml new file mode 100644 index 0000000..5f31104 --- /dev/null +++ b/kubernetes-vault/consul/templates/gateway-resources-job.yaml @@ -0,0 +1,108 @@ +{{- if .Values.apiGateway}}{{fail "[DEPRECATED and REMOVED] the apiGateway stanza is no longer supported as of Consul 1.19.0. Use connectInject.apiGateway instead."}}{{- end -}} +{{- if .Values.connectInject.enabled }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ template "consul.fullname" . }}-gateway-resources + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: gateway-resources + {{- if .Values.global.extraLabels }} + {{- toYaml .Values.global.extraLabels | nindent 4 }} + {{- end }} + annotations: + "helm.sh/hook": post-install,post-upgrade + "helm.sh/hook-weight": "0" + "helm.sh/hook-delete-policy": hook-succeeded +spec: + template: + metadata: + name: {{ template "consul.fullname" . }}-gateway-resources + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: gateway-resources + {{- if .Values.global.extraLabels }} + {{- toYaml .Values.global.extraLabels | nindent 8 }} + {{- end }} + annotations: + "consul.hashicorp.com/connect-inject": "false" + "consul.hashicorp.com/mesh-inject": "false" + spec: + restartPolicy: Never + serviceAccountName: {{ template "consul.fullname" . }}-gateway-resources + containers: + - name: gateway-resources + image: {{ .Values.global.imageK8S }} + {{ template "consul.imagePullPolicy" . }} + {{- include "consul.restrictedSecurityContext" . | nindent 10 }} + command: + - consul-k8s-control-plane + args: + - gateway-resources + - -gateway-class-name=consul + - -gateway-class-config-name=consul-api-gateway + - -controller-name=consul.hashicorp.com/gateway-controller + - -app={{template "consul.name" .}} + - -chart={{template "consul.chart" .}} + - -heritage={{ .Release.Service }} + - -release-name={{ .Release.Name }} + - -component=api-gateway + {{- if .Values.connectInject.apiGateway.managedGatewayClass.deployment }} + {{- if .Values.connectInject.apiGateway.managedGatewayClass.deployment.defaultInstances }} + - -deployment-default-instances={{ .Values.connectInject.apiGateway.managedGatewayClass.deployment.defaultInstances }} + {{- end}} + {{- if .Values.connectInject.apiGateway.managedGatewayClass.deployment.maxInstances }} + - -deployment-max-instances={{ .Values.connectInject.apiGateway.managedGatewayClass.deployment.maxInstances }} + {{- end}} + {{- if .Values.connectInject.apiGateway.managedGatewayClass.deployment.minInstances }} + - -deployment-min-instances={{ .Values.connectInject.apiGateway.managedGatewayClass.deployment.minInstances }} + {{- end}} + {{- end}} + {{- if .Values.connectInject.apiGateway.managedGatewayClass.nodeSelector }} + - -node-selector + - {{- toYaml .Values.connectInject.apiGateway.managedGatewayClass.nodeSelector | nindent 14 -}} + {{- end }} + {{- if .Values.connectInject.apiGateway.managedGatewayClass.tolerations }} + - -tolerations={{ .Values.connectInject.apiGateway.managedGatewayClass.tolerations }} + {{- end }} + {{- if .Values.connectInject.apiGateway.managedGatewayClass.copyAnnotations.service }} + - -service-annotations + - {{- toYaml .Values.connectInject.apiGateway.managedGatewayClass.copyAnnotations.service.annotations | nindent 14 -}} + {{- end }} + - -service-type={{ .Values.connectInject.apiGateway.managedGatewayClass.serviceType }} + {{- if .Values.global.openshift.enabled }} + - -openshift-scc-name={{ .Values.connectInject.apiGateway.managedGatewayClass.openshiftSCCName }} + {{- end }} + - -map-privileged-container-ports={{ .Values.connectInject.apiGateway.managedGatewayClass.mapPrivilegedContainerPorts }} + {{- if (ne (.Values.connectInject.apiGateway.managedGatewayClass.metrics.enabled | toString) "-") }} + - -enable-metrics={{ .Values.connectInject.apiGateway.managedGatewayClass.metrics.enabled | toString }} + {{- end }} + {{- if .Values.connectInject.apiGateway.managedGatewayClass.metrics.path }} + - -metrics-path={{ .Values.connectInject.apiGateway.managedGatewayClass.metrics.path }} + {{- end }} + {{- if .Values.connectInject.apiGateway.managedGatewayClass.metrics.port }} + - -metrics-port={{ .Values.connectInject.apiGateway.managedGatewayClass.metrics.port }} + {{- end }} + {{- with .Values.connectInject.apiGateway.managedGatewayClass.resourceJob.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + - name: config + mountPath: /consul/config + readOnly: true + {{- if .Values.global.acls.tolerations }} + tolerations: + {{ tpl .Values.global.acls.tolerations . | indent 8 | trim }} + {{- end }} + volumes: + - name: config + configMap: + name: {{ template "consul.fullname" . }}-gateway-resources-config +{{- end }} diff --git a/kubernetes-vault/consul/templates/gateway-resources-podsecuritypolicy.yaml b/kubernetes-vault/consul/templates/gateway-resources-podsecuritypolicy.yaml new file mode 100644 index 0000000..da52991 --- /dev/null +++ b/kubernetes-vault/consul/templates/gateway-resources-podsecuritypolicy.yaml @@ -0,0 +1,32 @@ +{{- if (and .Values.global.enablePodSecurityPolicies .Values.connectInject.enabled)}} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "consul.fullname" . }}-gateway-resources + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: gateway-resources +spec: + privileged: false + allowPrivilegeEscalation: false + # This is redundant with non-root + disallow privilege escalation, + # but we can provide it for defense in depth. + requiredDropCapabilities: + - ALL + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' + readOnlyRootFilesystem: false +{{- end }} diff --git a/kubernetes-vault/consul/templates/gateway-resources-serviceaccount.yaml b/kubernetes-vault/consul/templates/gateway-resources-serviceaccount.yaml new file mode 100644 index 0000000..db3a449 --- /dev/null +++ b/kubernetes-vault/consul/templates/gateway-resources-serviceaccount.yaml @@ -0,0 +1,19 @@ +{{- if .Values.connectInject.enabled }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "consul.fullname" . }}-gateway-resources + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: gateway-resources +{{- with .Values.global.imagePullSecrets }} +imagePullSecrets: +{{- range . }} + - name: {{ .name }} +{{- end }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/gossip-encryption-autogenerate-job.yaml b/kubernetes-vault/consul/templates/gossip-encryption-autogenerate-job.yaml new file mode 100644 index 0000000..485064f --- /dev/null +++ b/kubernetes-vault/consul/templates/gossip-encryption-autogenerate-job.yaml @@ -0,0 +1,71 @@ +{{- if .Values.global.gossipEncryption.autoGenerate }} +{{- if (or .Values.global.gossipEncryption.secretName .Values.global.gossipEncryption.secretKey) }} + {{ fail "If global.gossipEncryption.autoGenerate is true, global.gossipEncryption.secretName and global.gossipEncryption.secretKey must not be set." }} +{{ end }} +# automatically generate encryption key for gossip protocol and save it in Kubernetes secret +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ template "consul.fullname" . }}-gossip-encryption-autogenerate + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: gossip-encryption-autogenerate + {{- if .Values.global.extraLabels }} + {{- toYaml .Values.global.extraLabels | nindent 4 }} + {{- end }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-weight": "1" + "helm.sh/hook-delete-policy": hook-succeeded,before-hook-creation +spec: + template: + metadata: + name: {{ template "consul.fullname" . }}-gossip-encryption-autogenerate + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: gossip-encryption-autogenerate + {{- if .Values.global.extraLabels }} + {{- toYaml .Values.global.extraLabels | nindent 8 }} + {{- end }} + annotations: + "consul.hashicorp.com/connect-inject": "false" + "consul.hashicorp.com/mesh-inject": "false" + spec: + restartPolicy: Never + serviceAccountName: {{ template "consul.fullname" . }}-gossip-encryption-autogenerate + {{- if not .Values.global.openshift.enabled }} + securityContext: + runAsNonRoot: true + runAsGroup: 1000 + runAsUser: 100 + fsGroup: 1000 + {{- end }} + containers: + - name: gossip-encryption-autogen + image: "{{ .Values.global.imageK8S }}" + {{ template "consul.imagePullPolicy" . }} + {{- include "consul.restrictedSecurityContext" . | nindent 10 }} + command: + - "/bin/sh" + - "-ec" + - | + exec consul-k8s-control-plane gossip-encryption-autogenerate \ + -namespace={{ .Release.Namespace }} \ + -secret-name={{ template "consul.fullname" . }}-gossip-encryption-key \ + -secret-key="key" \ + -log-level={{ default .Values.global.logLevel .Values.global.gossipEncryption.logLevel }} \ + -log-json={{ .Values.global.logJSON }} + resources: + requests: + memory: "50Mi" + cpu: "50m" + limits: + memory: "50Mi" + cpu: "50m" +{{- end }} diff --git a/kubernetes-vault/consul/templates/gossip-encryption-autogenerate-podsecuritypolicy.yaml b/kubernetes-vault/consul/templates/gossip-encryption-autogenerate-podsecuritypolicy.yaml new file mode 100644 index 0000000..209b3aa --- /dev/null +++ b/kubernetes-vault/consul/templates/gossip-encryption-autogenerate-podsecuritypolicy.yaml @@ -0,0 +1,40 @@ +{{- if and .Values.global.gossipEncryption.autoGenerate .Values.global.enablePodSecurityPolicies }} +--- +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "consul.fullname" . }}-gossip-encryption-autogenerate + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: gossip-encryption-autogenerate + annotations: + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-delete-policy": before-hook-creation +spec: + privileged: false + # Required to prevent escalations to root. + allowPrivilegeEscalation: false + # This is redundant with non-root + disallow privilege escalation, + # but we can provide it for defense in depth. + requiredDropCapabilities: + - ALL + # Allow core volume types. + volumes: + - 'secret' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' + readOnlyRootFilesystem: false +{{- end }} diff --git a/kubernetes-vault/consul/templates/gossip-encryption-autogenerate-role.yaml b/kubernetes-vault/consul/templates/gossip-encryption-autogenerate-role.yaml new file mode 100644 index 0000000..8c51c96 --- /dev/null +++ b/kubernetes-vault/consul/templates/gossip-encryption-autogenerate-role.yaml @@ -0,0 +1,32 @@ +{{- if .Values.global.gossipEncryption.autoGenerate }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "consul.fullname" . }}-gossip-encryption-autogenerate + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: gossip-encryption-autogenerate + annotations: + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-delete-policy": before-hook-creation +rules: +- apiGroups: [""] + resources: + - secrets + verbs: + - create + - get +{{- if .Values.global.enablePodSecurityPolicies }} +- apiGroups: ["policy"] + resources: + - podsecuritypolicies + verbs: + - use + resourceNames: + - {{ template "consul.fullname" . }}-gossip-encryption-autogenerate +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/gossip-encryption-autogenerate-rolebinding.yaml b/kubernetes-vault/consul/templates/gossip-encryption-autogenerate-rolebinding.yaml new file mode 100644 index 0000000..7118475 --- /dev/null +++ b/kubernetes-vault/consul/templates/gossip-encryption-autogenerate-rolebinding.yaml @@ -0,0 +1,23 @@ +{{- if .Values.global.gossipEncryption.autoGenerate }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "consul.fullname" . }}-gossip-encryption-autogenerate + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: gossip-encryption-autogenerate + annotations: + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-delete-policy": before-hook-creation +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "consul.fullname" . }}-gossip-encryption-autogenerate +subjects: +- kind: ServiceAccount + name: {{ template "consul.fullname" . }}-gossip-encryption-autogenerate +{{- end }} diff --git a/kubernetes-vault/consul/templates/gossip-encryption-autogenerate-serviceaccount.yaml b/kubernetes-vault/consul/templates/gossip-encryption-autogenerate-serviceaccount.yaml new file mode 100644 index 0000000..1fd6202 --- /dev/null +++ b/kubernetes-vault/consul/templates/gossip-encryption-autogenerate-serviceaccount.yaml @@ -0,0 +1,22 @@ +{{- if .Values.global.gossipEncryption.autoGenerate }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "consul.fullname" . }}-gossip-encryption-autogenerate + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: gossip-encryption-autogenerate + annotations: + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-delete-policy": before-hook-creation +{{- with .Values.global.imagePullSecrets }} +imagePullSecrets: +{{- range . }} + - name: {{ .name }} +{{- end }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/ingress-gateways-deployment.yaml b/kubernetes-vault/consul/templates/ingress-gateways-deployment.yaml new file mode 100644 index 0000000..c7a38bb --- /dev/null +++ b/kubernetes-vault/consul/templates/ingress-gateways-deployment.yaml @@ -0,0 +1,379 @@ +{{- if .Values.ingressGateways.enabled }} +{{- if not .Values.connectInject.enabled }}{{ fail "connectInject.enabled must be true" }}{{ end -}} +{{- if and .Values.global.adminPartitions.enabled (not .Values.global.enableConsulNamespaces) }}{{ fail "global.enableConsulNamespaces must be true if global.adminPartitions.enabled=true" }}{{ end }} +{{- if .Values.global.lifecycleSidecarContainer }}{{ fail "global.lifecycleSidecarContainer has been renamed to global.consulSidecarContainer. Please set values using global.consulSidecarContainer." }}{{ end }} +{{ template "consul.validateRequiredCloudSecretsExist" . }} +{{ template "consul.validateCloudSecretKeys" . }} + +{{- $root := . }} +{{- $defaults := .Values.ingressGateways.defaults }} +{{- $names := dict }} + +{{- /* Check if gateway names are unique. */ -}} +{{- $gateways := .Values.ingressGateways.gateways }} +{{- range $outerIngressIndex, $outerIngressVal := $gateways }} + +{{- range $innerIngressIndex, $innerIngressVal := $gateways }} +{{- if (and (ne $outerIngressIndex $innerIngressIndex) (eq $outerIngressVal.name $innerIngressVal.name)) }} +{{ fail (cat "ingress gateways must have unique names but found duplicate name" $innerIngressVal.name) }} +{{ end -}} +{{ end -}} +{{ end -}} + +{{- range .Values.ingressGateways.gateways }} + +{{- $service := .service }} + +{{- if empty .name }} +# Check that the gateway name is provided +{{ fail "Ingress gateway names cannot be empty"}} +{{ end -}} +{{- if hasKey $names .name }} +# Check that the gateway name is unique +{{ fail "Ingress gateway names must be unique"}} +{{ end -}} +{{- /* Add the gateway name to the $names dict to ensure uniqueness */ -}} +{{- $_ := set $names .name .name }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "consul.fullname" $root }}-{{ .name }} + namespace: {{ $root.Release.Namespace }} + labels: + app: {{ template "consul.name" $root }} + chart: {{ template "consul.chart" $root }} + heritage: {{ $root.Release.Service }} + release: {{ $root.Release.Name }} + component: ingress-gateway + ingress-gateway-name: {{ template "consul.fullname" $root }}-{{ .name }} + {{- if $root.Values.global.extraLabels }} + {{- toYaml $root.Values.global.extraLabels | nindent 4 }} + {{- end }} +spec: + replicas: {{ default $defaults.replicas .replicas }} + selector: + matchLabels: + app: {{ template "consul.name" $root }} + chart: {{ template "consul.chart" $root }} + heritage: {{ $root.Release.Service }} + release: {{ $root.Release.Name }} + component: ingress-gateway + ingress-gateway-name: {{ template "consul.fullname" $root }}-{{ .name }} + template: + metadata: + labels: + app: {{ template "consul.name" $root }} + chart: {{ template "consul.chart" $root }} + heritage: {{ $root.Release.Service }} + release: {{ $root.Release.Name }} + component: ingress-gateway + ingress-gateway-name: {{ template "consul.fullname" $root }}-{{ .name }} + consul.hashicorp.com/connect-inject-managed-by: consul-k8s-endpoints-controller + {{- if $root.Values.global.extraLabels }} + {{- toYaml $root.Values.global.extraLabels | nindent 8 }} + {{- end }} + annotations: + "consul.hashicorp.com/connect-inject": "false" + "consul.hashicorp.com/mesh-inject": "false" + "consul.hashicorp.com/gateway-kind": "ingress-gateway" + "consul.hashicorp.com/gateway-consul-service-name": "{{ .name }}" + {{- if $root.Values.global.enableConsulNamespaces }} + "consul.hashicorp.com/gateway-namespace": {{ (default $defaults.consulNamespace .consulNamespace) }} + {{- end }} + "consul.hashicorp.com/gateway-wan-address-source": "Service" + {{- $serviceType := (default $defaults.service.type $service.type) }} + {{- if (eq $serviceType "NodePort") }} + {{- if $service.ports }} + {{- $firstPort := first $service.ports}} + {{- if $firstPort.nodePort }} + "consul.hashicorp.com/gateway-wan-port": "{{ $firstPort.nodePort }}" + {{- else }}{{ fail "if ingressGateways .service.type=NodePort and defining ingressGateways.gateways.service.ports, the first port entry must include a nodePort" }} + {{- end }} + {{- else if $defaults.service.ports }} + {{- $firstDefaultPort := first $defaults.service.ports}} + {{- if $firstDefaultPort.nodePort }} + "consul.hashicorp.com/gateway-wan-port": "{{ $firstDefaultPort.nodePort }}" + {{- else }}{{ fail "if ingressGateways .service.type=NodePort and using ingressGateways.defaults.service.ports, the first port entry must include a nodePort" }} + {{- end }} + {{- else }}{{ fail "if ingressGateways .service.type=NodePort, the first port entry in either the defaults or specific gateway must include a nodePort" }} + {{- end }} + {{- else }} + {{- if $service.ports }} + {{- $firstPort := first $service.ports}} + {{- if $firstPort.port }} + "consul.hashicorp.com/gateway-wan-port": "{{ $firstPort.port }}" + {{- else }}{{ fail "if ingressGateways .service.type is not NodePort and defining ingressGateways.gateways.service.ports, the first port entry must include a port" }} + {{- end }} + {{- else if $defaults.service.ports }} + {{- $firstDefaultPort := first $defaults.service.ports}} + {{- if $firstDefaultPort.port }} + "consul.hashicorp.com/gateway-wan-port": "{{ $firstDefaultPort.port }}" + {{- else }}{{ fail "if ingressGateways .service.type is not NodePort and using ingressGateways.defaults.service.ports, the first port entry must include a port" }} + {{- end }} + {{- else }}{{ fail "if ingressGateways .service.type is not NodePort, the first port entry in either the defaults or specific gateway must include a port" }} + {{- end }} + {{- end }} + {{- if (and $root.Values.global.secretsBackend.vault.enabled $root.Values.global.tls.enabled) }} + "vault.hashicorp.com/agent-init-first": "true" + "vault.hashicorp.com/agent-inject": "true" + "vault.hashicorp.com/role": {{ $root.Values.global.secretsBackend.vault.consulCARole }} + "vault.hashicorp.com/agent-inject-secret-serverca.crt": {{ $root.Values.global.tls.caCert.secretName }} + "vault.hashicorp.com/agent-inject-template-serverca.crt": {{ template "consul.serverTLSCATemplate" $root }} + {{- if and $root.Values.global.secretsBackend.vault.ca.secretName $root.Values.global.secretsBackend.vault.ca.secretKey }} + "vault.hashicorp.com/agent-extra-secret": {{ $root.Values.global.secretsBackend.vault.ca.secretName }} + "vault.hashicorp.com/ca-cert": /vault/custom/{{ $root.Values.global.secretsBackend.vault.ca.secretKey }} + {{- end }} + {{- if $root.Values.global.secretsBackend.vault.agentAnnotations }} + {{ tpl $root.Values.global.secretsBackend.vault.agentAnnotations $root | nindent 8 | trim }} + {{- end }} + {{- if (and ($root.Values.global.secretsBackend.vault.vaultNamespace) (not (hasKey (default "" $root.Values.global.secretsBackend.vault.agentAnnotations | fromYaml) "vault.hashicorp.com/namespace")))}} + "vault.hashicorp.com/namespace": "{{ $root.Values.global.secretsBackend.vault.vaultNamespace }}" + {{- end }} + {{- end }} + {{- if (and $root.Values.global.metrics.enabled $root.Values.global.metrics.enableGatewayMetrics) }} + "prometheus.io/scrape": "true" + {{- if not (hasKey (default "" $defaults.annotations | fromYaml) "prometheus.io/path")}} + "prometheus.io/path": "/metrics" + {{- end }} + "prometheus.io/port": "20200" + {{- end }} + {{- if $defaults.annotations }} + # We allow both default annotations and gateway-specific annotations + {{- tpl $defaults.annotations $root | nindent 8 }} + {{- end }} + {{- if .annotations }} + {{- tpl .annotations $root | nindent 8 }} + {{- end }} + spec: + {{- if (or $defaults.affinity .affinity) }} + affinity: + {{ tpl (default $defaults.affinity .affinity) $root | nindent 8 | trim }} + {{- end }} + {{- if (or $defaults.tolerations .tolerations) }} + tolerations: + {{ tpl (default $defaults.tolerations .tolerations) $root | nindent 8 | trim }} + {{- end }} + {{- if (or $defaults.topologySpreadConstraints .topologySpreadConstraints) }} + topologySpreadConstraints: + {{ tpl (default $defaults.topologySpreadConstraints .topologySpreadConstraints) $root | nindent 8 | trim }} + {{- end }} + terminationGracePeriodSeconds: {{ default $defaults.terminationGracePeriodSeconds .terminationGracePeriodSeconds }} + serviceAccountName: {{ template "consul.fullname" $root }}-{{ .name }} + volumes: + - name: tmp + emptyDir: + medium: "Memory" + - name: consul-service + emptyDir: + medium: "Memory" + {{- if $root.Values.global.tls.enabled }} + {{- if not (or (and $root.Values.externalServers.enabled $root.Values.externalServers.useSystemRoots) ($root.Values.global.secretsBackend.vault.enabled)) }} + - name: consul-ca-cert + secret: + {{- if $root.Values.global.tls.caCert.secretName }} + secretName: {{ $root.Values.global.tls.caCert.secretName }} + {{- else }} + secretName: {{ template "consul.fullname" $root }}-ca-cert + {{- end }} + items: + - key: {{ default "tls.crt" $root.Values.global.tls.caCert.secretKey }} + path: tls.crt + {{- end }} + {{- end }} + initContainers: + # ingress-gateway-init registers the ingress gateway service with Consul. + - name: ingress-gateway-init + image: {{ $root.Values.global.imageK8S }} + {{ template "consul.imagePullPolicy" $root }} + {{- include "consul.restrictedSecurityContext" $ | nindent 8 }} + env: + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + {{- include "consul.consulK8sConsulServerEnvVars" $root | nindent 8 }} + {{- if $root.Values.global.enableConsulNamespaces }} + - name: CONSUL_NAMESPACE + value: {{ (default $defaults.consulNamespace .consulNamespace) }} + {{- end }} + {{- if $root.Values.global.acls.manageSystemACLs }} + - name: CONSUL_LOGIN_AUTH_METHOD + value: {{ template "consul.fullname" $root }}-k8s-component-auth-method + - name: CONSUL_LOGIN_DATACENTER + value: {{ $root.Values.global.datacenter }} + - name: CONSUL_LOGIN_META + value: "component=ingress-gateway,pod=$(NAMESPACE)/$(POD_NAME)" + {{- end }} + - name: CONSUL_NODE_NAME + value: $(NODE_NAME)-virtual + command: + - "/bin/sh" + - "-ec" + - | + exec consul-k8s-control-plane connect-init -pod-name=${POD_NAME} -pod-namespace=${NAMESPACE} \ + -gateway-kind="ingress-gateway" \ + -proxy-id-file=/consul/service/proxy-id \ + -service-name={{ template "consul.fullname" $root }}-{{ .name }} \ + -log-level={{ default $root.Values.global.logLevel $root.Values.ingressGateways.logLevel }} \ + -log-json={{ $root.Values.global.logJSON }} + volumeMounts: + - name: tmp + mountPath: /tmp + - name: consul-service + mountPath: /consul/service + {{- if $root.Values.global.tls.enabled }} + {{- if not (or (and $root.Values.externalServers.enabled $root.Values.externalServers.useSystemRoots) ($root.Values.global.secretsBackend.vault.enabled)) }} + - name: consul-ca-cert + mountPath: /consul/tls/ca + readOnly: true + {{- end }} + {{- end }} + resources: + requests: + memory: "50Mi" + cpu: "50m" + limits: + memory: "50Mi" + cpu: "50m" + containers: + - name: ingress-gateway + image: {{ $root.Values.global.imageConsulDataplane | quote }} + {{ template "consul.imagePullPolicy" $root }} + {{- include "consul.restrictedSecurityContext" $ | nindent 8 }} + {{- if (default $defaults.resources .resources) }} + resources: {{ toYaml (default $defaults.resources .resources) | nindent 10 }} + {{- end }} + volumeMounts: + - name: tmp + mountPath: /tmp + - name: consul-service + mountPath: /consul/service + readOnly: true + {{- if $root.Values.global.tls.enabled }} + {{- if not (or (and $root.Values.externalServers.enabled $root.Values.externalServers.useSystemRoots) ($root.Values.global.secretsBackend.vault.enabled)) }} + - name: consul-ca-cert + mountPath: /consul/tls/ca + readOnly: true + {{- end }} + {{- end }} + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: DP_ENVOY_READY_BIND_ADDRESS + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: DP_CREDENTIAL_LOGIN_META1 + value: pod=$(NAMESPACE)/$(POD_NAME) + - name: DP_CREDENTIAL_LOGIN_META2 + value: component=ingress-gateway + - name: DP_SERVICE_NODE_NAME + value: $(NODE_NAME)-virtual + command: + - consul-dataplane + args: + - -envoy-ready-bind-port=21000 + {{- if $root.Values.externalServers.enabled }} + - -addresses={{ $root.Values.externalServers.hosts | first }} + {{- else }} + - -addresses={{ template "consul.fullname" $root }}-server.{{ $root.Release.Namespace }}.svc + {{- end }} + {{- if $root.Values.externalServers.enabled }} + - -grpc-port={{ $root.Values.externalServers.grpcPort }} + {{- else }} + - -grpc-port=8502 + {{- end }} + - -proxy-service-id-path=/consul/service/proxy-id + {{- if $root.Values.global.enableConsulNamespaces }} + - -service-namespace={{ (default $defaults.consulNamespace .consulNamespace) }} + {{- end }} + {{- if and $root.Values.global.tls.enabled }} + {{- if (not (and $root.Values.externalServers.enabled $root.Values.externalServers.useSystemRoots)) }} + {{- if $root.Values.global.secretsBackend.vault.enabled }} + - -ca-certs=/vault/secrets/serverca.crt + {{- else }} + - -ca-certs=/consul/tls/ca/tls.crt + {{- end }} + {{- end }} + {{- if and $root.Values.externalServers.enabled $root.Values.externalServers.tlsServerName }} + - -tls-server-name={{ $root.Values.externalServers.tlsServerName }} + {{- else if $root.Values.global.cloud.enabled }} + - -tls-server-name=server.{{ $root.Values.global.datacenter}}.{{ $root.Values.global.domain}} + {{- end }} + {{- else }} + - -tls-disabled + {{- end }} + {{- if $root.Values.global.acls.manageSystemACLs }} + - -credential-type=login + - -login-bearer-token-path=/var/run/secrets/kubernetes.io/serviceaccount/token + - -login-auth-method={{ template "consul.fullname" $root }}-k8s-component-auth-method + {{- if $root.Values.global.adminPartitions.enabled }} + - -login-partition={{ $root.Values.global.adminPartitions.name }} + {{- end }} + {{- end }} + {{- if $root.Values.global.adminPartitions.enabled }} + - -service-partition={{ $root.Values.global.adminPartitions.name }} + {{- end }} + - -log-level={{ default $root.Values.global.logLevel $root.Values.ingressGateways.logLevel }} + - -log-json={{ $root.Values.global.logJSON }} + {{- if (and $root.Values.global.metrics.enabled $root.Values.global.metrics.enableGatewayMetrics) }} + - -telemetry-prom-scrape-path=/metrics + {{- end }} + {{- if and $root.Values.externalServers.enabled $root.Values.externalServers.skipServerWatch }} + - -server-watch-disabled=true + {{- end }} + livenessProbe: + tcpSocket: + port: 21000 + failureThreshold: 3 + initialDelaySeconds: 30 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + readinessProbe: + tcpSocket: + port: 21000 + failureThreshold: 3 + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + ports: + - name: gateway-health + containerPort: 21000 + {{- range $index, $allPorts := (default $defaults.service.ports $service.ports) }} + - name: gateway-{{ $index }} + containerPort: {{ $allPorts.port }} + {{- end }} + {{- if (default $defaults.priorityClassName .priorityClassName) }} + priorityClassName: {{ default $defaults.priorityClassName .priorityClassName | quote }} + {{- end }} + {{- if (default $defaults.nodeSelector .nodeSelector) }} + nodeSelector: + {{ tpl (default $defaults.nodeSelector .nodeSelector) $root | indent 8 | trim }} + {{- end }} +--- +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/ingress-gateways-podsecuritypolicy.yaml b/kubernetes-vault/consul/templates/ingress-gateways-podsecuritypolicy.yaml new file mode 100644 index 0000000..b847e44 --- /dev/null +++ b/kubernetes-vault/consul/templates/ingress-gateways-podsecuritypolicy.yaml @@ -0,0 +1,47 @@ +{{- if (and .Values.global.enablePodSecurityPolicies .Values.ingressGateways.enabled) }} +{{- $root := . }} +{{- range .Values.ingressGateways.gateways }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "consul.fullname" $root }}-{{ .name }} + namespace: {{ $root.Release.Namespace }} + labels: + app: {{ template "consul.name" $root }} + chart: {{ template "consul.chart" $root }} + heritage: {{ $root.Release.Service }} + release: {{ $root.Release.Name }} + component: ingress-gateway + ingress-gateway-name: {{ template "consul.fullname" $root }}-{{ .name }} +spec: + privileged: false + # Required to prevent escalations to root. + allowPrivilegeEscalation: false + # This is redundant with non-root + disallow privilege escalation, + # but we can provide it for defense in depth. + requiredDropCapabilities: + - ALL + defaultAddCapabilities: + - NET_BIND_SERVICE + # Allow core volume types. + volumes: + - 'configMap' + - 'emptyDir' + - 'projected' + - 'secret' + - 'downwardAPI' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' + readOnlyRootFilesystem: false +--- +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/ingress-gateways-role.yaml b/kubernetes-vault/consul/templates/ingress-gateways-role.yaml new file mode 100644 index 0000000..49e8486 --- /dev/null +++ b/kubernetes-vault/consul/templates/ingress-gateways-role.yaml @@ -0,0 +1,46 @@ +{{- if .Values.ingressGateways.enabled }} + +{{- $root := . }} +{{- $defaults := .Values.ingressGateways.defaults }} + +{{- range .Values.ingressGateways.gateways }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "consul.fullname" $root }}-{{ .name }} + namespace: {{ $root.Release.Namespace }} + labels: + app: {{ template "consul.name" $root }} + chart: {{ template "consul.chart" $root }} + heritage: {{ $root.Release.Service }} + release: {{ $root.Release.Name }} + component: ingress-gateway + ingress-gateway-name: {{ template "consul.fullname" $root }}-{{ .name }} +rules: + - apiGroups: [""] + resources: + - services + resourceNames: + - {{ template "consul.fullname" $root }}-{{ .name }} + verbs: + - get +{{- if $root.Values.global.enablePodSecurityPolicies }} + - apiGroups: ["policy"] + resources: ["podsecuritypolicies"] + resourceNames: + - {{ template "consul.fullname" $root }}-{{ .name }} + verbs: + - use +{{- end }} +{{- if $root.Values.global.acls.manageSystemACLs }} + - apiGroups: [""] + resources: + - secrets + resourceNames: + - {{ template "consul.fullname" $root }}-{{ .name }}-acl-token + verbs: + - get +{{- end }} +--- +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/ingress-gateways-rolebinding.yaml b/kubernetes-vault/consul/templates/ingress-gateways-rolebinding.yaml new file mode 100644 index 0000000..601de77 --- /dev/null +++ b/kubernetes-vault/consul/templates/ingress-gateways-rolebinding.yaml @@ -0,0 +1,25 @@ +{{- if .Values.ingressGateways.enabled }} +{{- $root := . }} +{{- range .Values.ingressGateways.gateways }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "consul.fullname" $root }}-{{ .name }} + namespace: {{ $root.Release.Namespace }} + labels: + app: {{ template "consul.name" $root }} + chart: {{ template "consul.chart" $root }} + heritage: {{ $root.Release.Service }} + release: {{ $root.Release.Name }} + component: ingress-gateway + ingress-gateway-name: {{ template "consul.fullname" $root }}-{{ .name }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "consul.fullname" $root }}-{{ .name }} +subjects: + - kind: ServiceAccount + name: {{ template "consul.fullname" $root }}-{{ .name }} +--- +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/ingress-gateways-service.yaml b/kubernetes-vault/consul/templates/ingress-gateways-service.yaml new file mode 100644 index 0000000..cf54a74 --- /dev/null +++ b/kubernetes-vault/consul/templates/ingress-gateways-service.yaml @@ -0,0 +1,51 @@ +{{- if .Values.ingressGateways.enabled }} + +{{- $root := . }} +{{- $defaults := .Values.ingressGateways.defaults }} + +{{- range .Values.ingressGateways.gateways }} + +{{- $service := .service }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "consul.fullname" $root }}-{{ .name }} + namespace: {{ $root.Release.Namespace }} + labels: + app: {{ template "consul.name" $root }} + chart: {{ template "consul.chart" $root }} + heritage: {{ $root.Release.Service }} + release: {{ $root.Release.Name }} + component: ingress-gateway + ingress-gateway-name: {{ template "consul.fullname" $root }}-{{ .name }} + {{- if (or $defaults.service.annotations $service.annotations) }} + # We allow both default annotations and gateway-specific annotations + annotations: + {{- if $defaults.service.annotations }} + {{ tpl $defaults.service.annotations $root | nindent 4 | trim }} + {{- end }} + {{- if $service.annotations }} + {{ tpl $service.annotations $root | nindent 4 | trim }} + {{- end }} + {{- end }} +spec: + selector: + app: {{ template "consul.name" $root }} + release: "{{ $root.Release.Name }}" + component: ingress-gateway + ingress-gateway-name: {{ template "consul.fullname" $root }}-{{ .name }} + ports: + {{- range $index, $ports := (default $defaults.service.ports $service.ports) }} + - name: gateway-{{ $index }} + port: {{ $ports.port }} + {{- if (and (eq (default $defaults.service.type $service.type) "NodePort") $ports.nodePort) }} + nodePort: {{ $ports.nodePort }} + {{- end}} + {{- end }} + type: {{ default $defaults.service.type $service.type }} + {{- if (default $defaults.service.additionalSpec $service.additionalSpec) }} + {{ tpl (default $defaults.service.additionalSpec $service.additionalSpec) $root | nindent 2 | trim }} + {{- end }} +--- +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/ingress-gateways-serviceaccount.yaml b/kubernetes-vault/consul/templates/ingress-gateways-serviceaccount.yaml new file mode 100644 index 0000000..cea6caf --- /dev/null +++ b/kubernetes-vault/consul/templates/ingress-gateways-serviceaccount.yaml @@ -0,0 +1,35 @@ +{{- if .Values.ingressGateways.enabled }} +{{- $root := . }} +{{- $defaults := .Values.ingressGateways.defaults }} +{{- range .Values.ingressGateways.gateways }} +{{- $serviceAccount := .serviceAccount }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "consul.fullname" $root }}-{{ .name }} + namespace: {{ $root.Release.Namespace }} + labels: + app: {{ template "consul.name" $root }} + chart: {{ template "consul.chart" $root }} + heritage: {{ $root.Release.Service }} + release: {{ $root.Release.Name }} + component: ingress-gateway + ingress-gateway-name: {{ template "consul.fullname" $root }}-{{ .name }} + {{- if (or $defaults.serviceAccount.annotations $serviceAccount.annotations) }} + annotations: + {{- if $defaults.serviceAccount.annotations }} + {{ tpl $defaults.serviceAccount.annotations $root | nindent 4 | trim }} + {{- end }} + {{- if $serviceAccount.annotations }} + {{ tpl $serviceAccount.annotations $root | nindent 4 | trim }} + {{- end }} + {{- end }} +{{- with $root.Values.global.imagePullSecrets }} +imagePullSecrets: +{{- range . }} + - name: {{ .name }} +{{- end }} +{{- end }} +--- +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/mesh-gateway-clusterrole.yaml b/kubernetes-vault/consul/templates/mesh-gateway-clusterrole.yaml new file mode 100644 index 0000000..3053105 --- /dev/null +++ b/kubernetes-vault/consul/templates/mesh-gateway-clusterrole.yaml @@ -0,0 +1,36 @@ +{{- if .Values.meshGateway.enabled }} +{{- if not (mustHas "resource-apis" .Values.global.experiments) }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "consul.fullname" . }}-mesh-gateway + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: mesh-gateway +{{- if or .Values.global.acls.manageSystemACLs .Values.global.enablePodSecurityPolicies (eq .Values.meshGateway.wanAddress.source "Service") }} +rules: +{{- if .Values.global.enablePodSecurityPolicies }} + - apiGroups: ["policy"] + resources: ["podsecuritypolicies"] + resourceNames: + - {{ template "consul.fullname" . }}-mesh-gateway + verbs: + - use +{{- end }} +{{- if eq .Values.meshGateway.wanAddress.source "Service" }} + - apiGroups: [""] + resources: + - services + resourceNames: + - {{ template "consul.fullname" . }}-mesh-gateway + verbs: + - get + {{- end }} +{{- else }} +rules: [] +{{- end }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/mesh-gateway-clusterrolebinding.yaml b/kubernetes-vault/consul/templates/mesh-gateway-clusterrolebinding.yaml new file mode 100644 index 0000000..2fb80fc --- /dev/null +++ b/kubernetes-vault/consul/templates/mesh-gateway-clusterrolebinding.yaml @@ -0,0 +1,22 @@ +{{- if .Values.meshGateway.enabled }} +{{- if not (mustHas "resource-apis" .Values.global.experiments) }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "consul.fullname" . }}-mesh-gateway + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: mesh-gateway +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "consul.fullname" . }}-mesh-gateway +subjects: + - kind: ServiceAccount + name: {{ template "consul.fullname" . }}-mesh-gateway + namespace: {{ .Release.Namespace }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/mesh-gateway-deployment.yaml b/kubernetes-vault/consul/templates/mesh-gateway-deployment.yaml new file mode 100644 index 0000000..03bf270 --- /dev/null +++ b/kubernetes-vault/consul/templates/mesh-gateway-deployment.yaml @@ -0,0 +1,325 @@ +{{- if .Values.meshGateway.enabled }} +{{- if not (mustHas "resource-apis" .Values.global.experiments) }} +{{- if not .Values.connectInject.enabled }}{{ fail "connectInject.enabled must be true" }}{{ end -}} +{{- if and .Values.global.acls.manageSystemACLs (ne .Values.meshGateway.consulServiceName "") (ne .Values.meshGateway.consulServiceName "mesh-gateway") }}{{ fail "if global.acls.manageSystemACLs is true, meshGateway.consulServiceName cannot be set" }}{{ end -}} +{{- if .Values.meshGateway.globalMode }}{{ fail "meshGateway.globalMode is no longer supported; instead, you must migrate to CRDs (see www.consul.io/docs/k8s/crds/upgrade-to-crds)" }}{{ end -}} +{{- if and .Values.global.adminPartitions.enabled (not .Values.global.enableConsulNamespaces) }}{{ fail "global.enableConsulNamespaces must be true if global.adminPartitions.enabled=true" }}{{ end }} +{{- if and (eq .Values.meshGateway.wanAddress.source "Static") (eq .Values.meshGateway.wanAddress.static "") }}{{ fail "if meshGateway.wanAddress.source=Static then meshGateway.wanAddress.static cannot be empty" }}{{ end }} +{{- if and (eq .Values.meshGateway.wanAddress.source "Service") (eq .Values.meshGateway.service.type "NodePort") (not .Values.meshGateway.service.nodePort) }}{{ fail "if meshGateway.wanAddress.source=Service and meshGateway.service.type=NodePort, meshGateway.service.nodePort must be set" }}{{ end }} +{{ template "consul.validateRequiredCloudSecretsExist" . }} +{{ template "consul.validateCloudSecretKeys" . }} + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "consul.fullname" . }}-mesh-gateway + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: mesh-gateway + {{- if .Values.global.extraLabels }} + {{- toYaml .Values.global.extraLabels | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.meshGateway.replicas }} + selector: + matchLabels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: mesh-gateway + template: + metadata: + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: mesh-gateway + consul.hashicorp.com/connect-inject-managed-by: consul-k8s-endpoints-controller + {{- if .Values.global.extraLabels }} + {{- toYaml .Values.global.extraLabels | nindent 8 }} + {{- end }} + annotations: + "consul.hashicorp.com/connect-inject": "false" + "consul.hashicorp.com/mesh-inject": "false" + "consul.hashicorp.com/gateway-kind": "mesh-gateway" + "consul.hashicorp.com/gateway-consul-service-name": "{{ .Values.meshGateway.consulServiceName }}" + "consul.hashicorp.com/mesh-gateway-container-port": "{{ .Values.meshGateway.containerPort }}" + "consul.hashicorp.com/gateway-wan-address-source": "{{ .Values.meshGateway.wanAddress.source }}" + "consul.hashicorp.com/gateway-wan-address-static": "{{ .Values.meshGateway.wanAddress.static }}" + {{- if eq .Values.meshGateway.wanAddress.source "Service" }} + {{- if eq .Values.meshGateway.service.type "NodePort" }} + "consul.hashicorp.com/gateway-wan-port": "{{ .Values.meshGateway.service.nodePort }}" + {{- else }} + "consul.hashicorp.com/gateway-wan-port": "{{ .Values.meshGateway.service.port }}" + {{- end }} + {{- else }} + "consul.hashicorp.com/gateway-wan-port": "{{ .Values.meshGateway.wanAddress.port }}" + {{- end }} + {{- if (and .Values.global.secretsBackend.vault.enabled .Values.global.tls.enabled) }} + "vault.hashicorp.com/agent-init-first": "true" + "vault.hashicorp.com/agent-inject": "true" + "vault.hashicorp.com/role": {{ .Values.global.secretsBackend.vault.consulCARole }} + "vault.hashicorp.com/agent-inject-secret-serverca.crt": {{ .Values.global.tls.caCert.secretName }} + "vault.hashicorp.com/agent-inject-template-serverca.crt": {{ template "consul.serverTLSCATemplate" . }} + {{- if and .Values.global.secretsBackend.vault.ca.secretName .Values.global.secretsBackend.vault.ca.secretKey }} + "vault.hashicorp.com/agent-extra-secret": "{{ .Values.global.secretsBackend.vault.ca.secretName }}" + "vault.hashicorp.com/ca-cert": "/vault/custom/{{ .Values.global.secretsBackend.vault.ca.secretKey }}" + {{- end }} + {{- if .Values.global.secretsBackend.vault.agentAnnotations }} + {{ tpl .Values.global.secretsBackend.vault.agentAnnotations . | nindent 8 | trim }} + {{- end }} + {{- if (and (.Values.global.secretsBackend.vault.vaultNamespace) (not (hasKey (default "" .Values.global.secretsBackend.vault.agentAnnotations | fromYaml) "vault.hashicorp.com/namespace")))}} + "vault.hashicorp.com/namespace": "{{ .Values.global.secretsBackend.vault.vaultNamespace }}" + {{- end }} + {{- end }} + {{- if (and .Values.global.metrics.enabled .Values.global.metrics.enableGatewayMetrics) }} + "prometheus.io/scrape": "true" + {{- if not (hasKey (default "" .Values.meshGateway.annotations | fromYaml) "prometheus.io/path")}} + "prometheus.io/path": "/metrics" + {{- end }} + "prometheus.io/port": "20200" + {{- end }} + {{- if .Values.meshGateway.annotations }} + {{- tpl .Values.meshGateway.annotations . | nindent 8 }} + {{- end }} + spec: + {{- if .Values.meshGateway.affinity }} + affinity: + {{ tpl .Values.meshGateway.affinity . | nindent 8 | trim }} + {{- end }} + {{- if .Values.meshGateway.tolerations }} + tolerations: + {{ tpl .Values.meshGateway.tolerations . | nindent 8 | trim }} + {{- end }} + {{- if .Values.meshGateway.topologySpreadConstraints }} + topologySpreadConstraints: + {{ tpl .Values.meshGateway.topologySpreadConstraints . | nindent 8 | trim }} + {{- end }} + terminationGracePeriodSeconds: 10 + serviceAccountName: {{ template "consul.fullname" . }}-mesh-gateway + volumes: + - name: consul-service + emptyDir: + medium: "Memory" + {{- if .Values.global.tls.enabled }} + {{- if not (or (and .Values.externalServers.enabled .Values.externalServers.useSystemRoots) .Values.global.secretsBackend.vault.enabled) }} + - name: consul-ca-cert + secret: + {{- if .Values.global.tls.caCert.secretName }} + secretName: {{ .Values.global.tls.caCert.secretName }} + {{- else }} + secretName: {{ template "consul.fullname" . }}-ca-cert + {{- end }} + items: + - key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }} + path: tls.crt + {{- end }} + {{- end }} + {{- if .Values.meshGateway.hostNetwork }} + hostNetwork: {{ .Values.meshGateway.hostNetwork }} + {{- end }} + {{- if .Values.meshGateway.dnsPolicy }} + dnsPolicy: {{ .Values.meshGateway.dnsPolicy }} + {{- end }} + initContainers: + - name: mesh-gateway-init + image: {{ .Values.global.imageK8S }} + {{ template "consul.imagePullPolicy" . }} + env: + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + {{- include "consul.consulK8sConsulServerEnvVars" . | nindent 8 }} + {{- if .Values.global.acls.manageSystemACLs }} + - name: CONSUL_LOGIN_AUTH_METHOD + {{- if and .Values.global.federation.enabled .Values.global.federation.primaryDatacenter }} + value: {{ template "consul.fullname" . }}-k8s-component-auth-method-{{ .Values.global.datacenter }} + {{- else }} + value: {{ template "consul.fullname" . }}-k8s-component-auth-method + {{- end }} + - name: CONSUL_LOGIN_DATACENTER + {{- if and .Values.global.federation.enabled .Values.global.federation.primaryDatacenter }} + value: {{ .Values.global.federation.primaryDatacenter }} + {{- else }} + value: {{ .Values.global.datacenter }} + {{- end }} + - name: CONSUL_LOGIN_META + value: "component=mesh-gateway,pod=$(NAMESPACE)/$(POD_NAME)" + {{- end }} + - name: CONSUL_NODE_NAME + value: $(NODE_NAME)-virtual + command: + - "/bin/sh" + - "-ec" + - | + exec consul-k8s-control-plane connect-init -pod-name=${POD_NAME} -pod-namespace=${NAMESPACE} \ + -gateway-kind="mesh-gateway" \ + -proxy-id-file=/consul/service/proxy-id \ + -service-name={{ .Values.meshGateway.consulServiceName }} \ + -log-level={{ default .Values.global.logLevel .Values.meshGateway.logLevel }} \ + -log-json={{ .Values.global.logJSON }} + volumeMounts: + - name: consul-service + mountPath: /consul/service + {{- if .Values.global.tls.enabled }} + {{- if not (or (and .Values.externalServers.enabled .Values.externalServers.useSystemRoots) .Values.global.secretsBackend.vault.enabled) }} + - name: consul-ca-cert + mountPath: /consul/tls/ca + readOnly: true + {{- end }} + {{- end }} + {{- if .Values.meshGateway.initServiceInitContainer.resources }} + resources: {{ toYaml .Values.meshGateway.initServiceInitContainer.resources | nindent 10 }} + {{- end }} + containers: + - name: mesh-gateway + image: {{ .Values.global.imageConsulDataplane | quote }} + {{ template "consul.imagePullPolicy" . }} + securityContext: + capabilities: + {{ if not .Values.meshGateway.hostNetwork}} + drop: + - ALL + {{- end }} + add: + - NET_BIND_SERVICE + {{- if .Values.meshGateway.resources }} + resources: + {{- if eq (typeOf .Values.meshGateway.resources) "string" }} + {{ tpl .Values.meshGateway.resources . | nindent 12 | trim }} + {{- else }} + {{- toYaml .Values.meshGateway.resources | nindent 12 }} + {{- end }} + {{- end }} + volumeMounts: + - mountPath: /consul/service + name: consul-service + readOnly: true + {{- if .Values.global.tls.enabled }} + {{- if not (or (and .Values.externalServers.enabled .Values.externalServers.useSystemRoots) .Values.global.secretsBackend.vault.enabled) }} + - name: consul-ca-cert + mountPath: /consul/tls/ca + readOnly: true + {{- end }} + {{- end }} + env: + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: DP_CREDENTIAL_LOGIN_META1 + value: pod=$(NAMESPACE)/$(POD_NAME) + - name: DP_CREDENTIAL_LOGIN_META2 + value: component=mesh-gateway + - name: DP_SERVICE_NODE_NAME + value: $(NODE_NAME)-virtual + command: + - consul-dataplane + args: + {{- if .Values.externalServers.enabled }} + - -addresses={{ .Values.externalServers.hosts | first }} + {{- else }} + - -addresses={{ template "consul.fullname" . }}-server.{{ .Release.Namespace }}.svc + {{- end }} + {{- if .Values.externalServers.enabled }} + - -grpc-port={{ .Values.externalServers.grpcPort }} + {{- else }} + - -grpc-port=8502 + {{- end }} + - -proxy-service-id-path=/consul/service/proxy-id + {{- if .Values.global.tls.enabled }} + {{- if (not (and .Values.externalServers.enabled .Values.externalServers.useSystemRoots)) }} + {{- if .Values.global.secretsBackend.vault.enabled }} + - -ca-certs=/vault/secrets/serverca.crt + {{- else }} + - -ca-certs=/consul/tls/ca/tls.crt + {{- end }} + {{- end }} + {{- if and .Values.externalServers.enabled .Values.externalServers.tlsServerName }} + - -tls-server-name={{.Values.externalServers.tlsServerName }} + {{- else if .Values.global.cloud.enabled }} + - -tls-server-name=server.{{ .Values.global.datacenter}}.{{ .Values.global.domain}} + {{- end }} + {{- else }} + - -tls-disabled + {{- end }} + {{- if .Values.global.acls.manageSystemACLs }} + - -credential-type=login + - -login-bearer-token-path=/var/run/secrets/kubernetes.io/serviceaccount/token + {{- if and .Values.global.federation.enabled .Values.global.federation.primaryDatacenter }} + - -login-auth-method={{ template "consul.fullname" . }}-k8s-component-auth-method-{{ .Values.global.datacenter }} + - -login-datacenter={{ .Values.global.federation.primaryDatacenter }} + {{- else }} + - -login-auth-method={{ template "consul.fullname" . }}-k8s-component-auth-method + {{- end }} + {{- if .Values.global.adminPartitions.enabled }} + - -login-partition={{ .Values.global.adminPartitions.name }} + {{- end }} + {{- end }} + {{- if .Values.global.adminPartitions.enabled }} + - -service-partition={{ .Values.global.adminPartitions.name }} + {{- end }} + - -log-level={{ default .Values.global.logLevel .Values.meshGateway.logLevel }} + - -log-json={{ .Values.global.logJSON }} + {{- if (and .Values.global.metrics.enabled .Values.global.metrics.enableGatewayMetrics) }} + - -telemetry-prom-scrape-path=/metrics + {{- end }} + {{- if and .Values.externalServers.enabled .Values.externalServers.skipServerWatch }} + - -server-watch-disabled=true + {{- end }} + livenessProbe: + tcpSocket: + port: {{ .Values.meshGateway.containerPort }} + failureThreshold: 3 + initialDelaySeconds: 30 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + readinessProbe: + tcpSocket: + port: {{ .Values.meshGateway.containerPort }} + failureThreshold: 3 + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + ports: + - name: gateway + containerPort: {{ .Values.meshGateway.containerPort }} + {{- if .Values.meshGateway.hostPort }} + hostPort: {{ .Values.meshGateway.hostPort }} + {{- end }} + {{- if .Values.meshGateway.priorityClassName }} + priorityClassName: {{ .Values.meshGateway.priorityClassName | quote }} + {{- end }} + {{- if .Values.meshGateway.nodeSelector }} + nodeSelector: + {{ tpl .Values.meshGateway.nodeSelector . | indent 8 | trim }} + {{- end }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/mesh-gateway-podsecuritypolicy.yaml b/kubernetes-vault/consul/templates/mesh-gateway-podsecuritypolicy.yaml new file mode 100644 index 0000000..56e4b79 --- /dev/null +++ b/kubernetes-vault/consul/templates/mesh-gateway-podsecuritypolicy.yaml @@ -0,0 +1,56 @@ +{{- if and .Values.global.enablePodSecurityPolicies .Values.meshGateway.enabled }} +{{- if not (mustHas "resource-apis" .Values.global.experiments) }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "consul.fullname" . }}-mesh-gateway + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: mesh-gateway +spec: + privileged: false + # Required to prevent escalations to root. + allowPrivilegeEscalation: false + # This is redundant with non-root + disallow privilege escalation, + # but we can provide it for defense in depth. + requiredDropCapabilities: + - ALL + defaultAddCapabilities: + - NET_BIND_SERVICE + # Allow core volume types. + volumes: + - 'configMap' + - 'emptyDir' + - 'projected' + - 'secret' + - 'downwardAPI' + {{- if .Values.meshGateway.hostNetwork }} + hostNetwork: {{ .Values.meshGateway.hostNetwork }} + {{- else }} + hostNetwork: false + {{- end }} + hostPorts: + {{- if .Values.meshGateway.hostPort }} + - min: {{ .Values.meshGateway.hostPort }} + max: {{ .Values.meshGateway.hostPort }} + {{- else if .Values.meshGateway.hostNetwork }} + - min: {{ .Values.meshGateway.containerPort }} + max: {{ .Values.meshGateway.containerPort }} + {{- end }} + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' + readOnlyRootFilesystem: false +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/mesh-gateway-service.yaml b/kubernetes-vault/consul/templates/mesh-gateway-service.yaml new file mode 100644 index 0000000..80f82ac --- /dev/null +++ b/kubernetes-vault/consul/templates/mesh-gateway-service.yaml @@ -0,0 +1,35 @@ +{{- if and .Values.meshGateway.enabled }} +{{- if not (mustHas "resource-apis" .Values.global.experiments) }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "consul.fullname" . }}-mesh-gateway + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: mesh-gateway + {{- if .Values.meshGateway.service.annotations }} + annotations: + {{ tpl .Values.meshGateway.service.annotations . | nindent 4 | trim }} + {{- end }} +spec: + selector: + app: {{ template "consul.name" . }} + release: "{{ .Release.Name }}" + component: mesh-gateway + ports: + - name: gateway + port: {{ .Values.meshGateway.service.port }} + targetPort: {{ .Values.meshGateway.containerPort }} + {{- if .Values.meshGateway.service.nodePort }} + nodePort: {{ .Values.meshGateway.service.nodePort }} + {{- end}} + type: {{ .Values.meshGateway.service.type }} + {{- if .Values.meshGateway.service.additionalSpec }} + {{ tpl .Values.meshGateway.service.additionalSpec . | nindent 2 | trim }} + {{- end }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/mesh-gateway-serviceaccount.yaml b/kubernetes-vault/consul/templates/mesh-gateway-serviceaccount.yaml new file mode 100644 index 0000000..b1a0661 --- /dev/null +++ b/kubernetes-vault/consul/templates/mesh-gateway-serviceaccount.yaml @@ -0,0 +1,25 @@ +{{- if .Values.meshGateway.enabled }} +{{- if not (mustHas "resource-apis" .Values.global.experiments) }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "consul.fullname" . }}-mesh-gateway + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: mesh-gateway + {{- if .Values.meshGateway.serviceAccount.annotations }} + annotations: + {{ tpl .Values.meshGateway.serviceAccount.annotations . | nindent 4 | trim }} + {{- end }} +{{- with .Values.global.imagePullSecrets }} +imagePullSecrets: +{{- range . }} + - name: {{ .name }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/partition-init-job.yaml b/kubernetes-vault/consul/templates/partition-init-job.yaml new file mode 100644 index 0000000..0ce8a92 --- /dev/null +++ b/kubernetes-vault/consul/templates/partition-init-job.yaml @@ -0,0 +1,132 @@ +{{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} +{{- if (and .Values.global.adminPartitions.enabled (not $serverEnabled) (ne .Values.global.adminPartitions.name "default")) }} +{{- template "consul.reservedNamesFailer" (list .Values.global.adminPartitions.name "global.adminPartitions.name") }} +{{- if and (not .Values.externalServers.enabled) (ne .Values.global.adminPartitions.name "default") }}{{ fail "externalServers.enabled needs to be true and configured to create a non-default partition." }}{{ end -}} +{{- if and .Values.global.secretsBackend.vault.enabled .Values.global.acls.manageSystemACLs (not .Values.global.secretsBackend.vault.adminPartitionsRole) }}{{ fail "global.secretsBackend.vault.adminPartitionsRole is required when global.secretsBackend.vault.enabled and global.acls.manageSystemACLs are true." }}{{ end -}} +{{- if and .Values.externalServers.enabled (not .Values.externalServers.hosts) }}{{ fail "externalServers.hosts must be set if externalServers.enabled is true" }}{{ end -}} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ template "consul.fullname" . }}-partition-init + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: partition-init + {{- if .Values.global.extraLabels }} + {{- toYaml .Values.global.extraLabels | nindent 4 }} + {{- end }} + annotations: + "helm.sh/hook": pre-install + "helm.sh/hook-weight": "2" + "helm.sh/hook-delete-policy": hook-succeeded,before-hook-creation +spec: + template: + metadata: + name: {{ template "consul.fullname" . }}-partition-init + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: partition-init + {{- if .Values.global.extraLabels }} + {{- toYaml .Values.global.extraLabels | nindent 8 }} + {{- end }} + annotations: + "consul.hashicorp.com/connect-inject": "false" + "consul.hashicorp.com/mesh-inject": "false" + {{- if (and .Values.global.secretsBackend.vault.enabled (or .Values.global.tls.enabled .Values.global.acls.manageSystemACLs)) }} + "vault.hashicorp.com/agent-pre-populate-only": "true" + "vault.hashicorp.com/agent-inject": "true" + {{- if .Values.global.acls.manageSystemACLs }} + "vault.hashicorp.com/role": {{ .Values.global.secretsBackend.vault.adminPartitionsRole }} + {{- if .Values.global.acls.bootstrapToken.secretName }} + {{- with .Values.global.acls.bootstrapToken }} + "vault.hashicorp.com/agent-inject-secret-bootstrap-token": "{{ .secretName }}" + "vault.hashicorp.com/agent-inject-template-bootstrap-token": {{ template "consul.vaultSecretTemplate" . }} + {{- end }} + {{- end }} + {{- else }} + "vault.hashicorp.com/role": {{ .Values.global.secretsBackend.vault.consulCARole }} + {{- end }} + "vault.hashicorp.com/agent-inject-secret-serverca.crt": {{ .Values.global.tls.caCert.secretName }} + "vault.hashicorp.com/agent-inject-template-serverca.crt": {{ template "consul.serverTLSCATemplate" . }} + {{- if and .Values.global.secretsBackend.vault.ca.secretName .Values.global.secretsBackend.vault.ca.secretKey }} + "vault.hashicorp.com/agent-extra-secret": "{{ .Values.global.secretsBackend.vault.ca.secretName }}" + "vault.hashicorp.com/ca-cert": "/vault/custom/{{ .Values.global.secretsBackend.vault.ca.secretKey }}" + {{- end }} + {{- if .Values.global.secretsBackend.vault.agentAnnotations }} + {{ tpl .Values.global.secretsBackend.vault.agentAnnotations . | nindent 8 | trim }} + {{- end }} + {{- if (and (.Values.global.secretsBackend.vault.vaultNamespace) (not (hasKey (default "" .Values.global.secretsBackend.vault.agentAnnotations | fromYaml) "vault.hashicorp.com/namespace")))}} + "vault.hashicorp.com/namespace": "{{ .Values.global.secretsBackend.vault.vaultNamespace }}" + {{- end }} + {{- end }} + spec: + restartPolicy: Never + serviceAccountName: {{ template "consul.fullname" . }}-partition-init + {{- if .Values.global.tls.enabled }} + {{- if not (or .Values.externalServers.useSystemRoots .Values.global.secretsBackend.vault.enabled) }} + volumes: + - name: consul-ca-cert + secret: + {{- if .Values.global.tls.caCert.secretName }} + secretName: {{ .Values.global.tls.caCert.secretName }} + {{- else }} + secretName: {{ template "consul.fullname" . }}-ca-cert + {{- end }} + items: + - key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }} + path: tls.crt + {{- end }} + {{- end }} + containers: + - name: partition-init-job + image: {{ .Values.global.imageK8S }} + {{ template "consul.imagePullPolicy" . }} + {{- include "consul.restrictedSecurityContext" . | nindent 10 }} + env: + {{- include "consul.consulK8sConsulServerEnvVars" . | nindent 10 }} + {{- if (and .Values.global.acls.bootstrapToken.secretName .Values.global.acls.bootstrapToken.secretKey) }} + {{- if .Values.global.secretsBackend.vault.enabled }} + - name: CONSUL_ACL_TOKEN_FILE + value: /vault/secrets/bootstrap-token + {{- else }} + - name: CONSUL_ACL_TOKEN + valueFrom: + secretKeyRef: + name: {{ .Values.global.acls.bootstrapToken.secretName }} + key: {{ .Values.global.acls.bootstrapToken.secretKey }} + {{- end }} + {{- end }} + {{- if .Values.global.tls.enabled }} + {{- if not (or .Values.externalServers.useSystemRoots .Values.global.secretsBackend.vault.enabled) }} + volumeMounts: + - name: consul-ca-cert + mountPath: /consul/tls/ca + readOnly: true + {{- end }} + {{- end }} + command: + - "/bin/sh" + - "-ec" + - | + exec consul-k8s-control-plane partition-init \ + -log-level={{ .Values.global.logLevel }} \ + -log-json={{ .Values.global.logJSON }} \ + {{- if .Values.global.cloud.enabled }} + -tls-server-name=server.{{ .Values.global.datacenter}}.{{ .Values.global.domain}} \ + {{- end }} + {{- if and (mustHas "resource-apis" .Values.global.experiments) (mustHas "v2tenancy" .Values.global.experiments) }} + -enable-v2tenancy=true + {{- end }} + resources: + requests: + memory: "50Mi" + cpu: "50m" + limits: + memory: "50Mi" + cpu: "50m" +{{- end }} diff --git a/kubernetes-vault/consul/templates/partition-init-podsecuritypolicy.yaml b/kubernetes-vault/consul/templates/partition-init-podsecuritypolicy.yaml new file mode 100644 index 0000000..2bc6782 --- /dev/null +++ b/kubernetes-vault/consul/templates/partition-init-podsecuritypolicy.yaml @@ -0,0 +1,40 @@ +{{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} +{{- if (and .Values.global.adminPartitions.enabled .Values.global.enablePodSecurityPolicies (not $serverEnabled)) }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "consul.fullname" . }}-partition-init + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: partition-init + annotations: + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-delete-policy": before-hook-creation +spec: + privileged: false + # Allow core volume types. + volumes: + - 'secret' + - 'emptyDir' + allowPrivilegeEscalation: false + # This is redundant with non-root + disallow privilege escalation, + # but we can provide it for defense in depth. + requiredDropCapabilities: + - ALL + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' + readOnlyRootFilesystem: false +{{- end }} diff --git a/kubernetes-vault/consul/templates/partition-init-role.yaml b/kubernetes-vault/consul/templates/partition-init-role.yaml new file mode 100644 index 0000000..340c59e --- /dev/null +++ b/kubernetes-vault/consul/templates/partition-init-role.yaml @@ -0,0 +1,35 @@ +{{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} +{{- if (and .Values.global.adminPartitions.enabled (not $serverEnabled)) }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "consul.fullname" . }}-partition-init + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: partition-init + annotations: + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-delete-policy": before-hook-creation +rules: +{{- if .Values.connectInject.enabled }} + - apiGroups: [""] + resources: + - serviceaccounts + resourceNames: + - {{ template "consul.fullname" . }}-connect-injector + verbs: + - get +{{- end }} +{{- if .Values.global.enablePodSecurityPolicies }} + - apiGroups: ["policy"] + resources: ["podsecuritypolicies"] + resourceNames: + - {{ template "consul.fullname" . }}-partition-init + verbs: + - use +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/partition-init-rolebinding.yaml b/kubernetes-vault/consul/templates/partition-init-rolebinding.yaml new file mode 100644 index 0000000..432d6df --- /dev/null +++ b/kubernetes-vault/consul/templates/partition-init-rolebinding.yaml @@ -0,0 +1,24 @@ +{{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} +{{- if (and .Values.global.adminPartitions.enabled (not $serverEnabled)) }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "consul.fullname" . }}-partition-init + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: partition-init + annotations: + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-delete-policy": before-hook-creation +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "consul.fullname" . }}-partition-init +subjects: + - kind: ServiceAccount + name: {{ template "consul.fullname" . }}-partition-init +{{- end }} diff --git a/kubernetes-vault/consul/templates/partition-init-serviceaccount.yaml b/kubernetes-vault/consul/templates/partition-init-serviceaccount.yaml new file mode 100644 index 0000000..65fcf43 --- /dev/null +++ b/kubernetes-vault/consul/templates/partition-init-serviceaccount.yaml @@ -0,0 +1,23 @@ +{{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} +{{- if (and .Values.global.adminPartitions.enabled (not $serverEnabled)) }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "consul.fullname" . }}-partition-init + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: partition-init + annotations: + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-delete-policy": before-hook-creation +{{- with .Values.global.imagePullSecrets }} +imagePullSecrets: +{{- range . }} + - name: {{ .name }} +{{- end }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/partition-name-configmap.yaml b/kubernetes-vault/consul/templates/partition-name-configmap.yaml new file mode 100644 index 0000000..ee330b0 --- /dev/null +++ b/kubernetes-vault/consul/templates/partition-name-configmap.yaml @@ -0,0 +1,19 @@ +{{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} +{{- if (and .Values.global.adminPartitions.enabled (not $serverEnabled)) }} +# Immutable ConfigMap which saves the partition name. Attempting to update this configmap +# with a new Admin Partition name will cause the helm upgrade to fail +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "consul.fullname" . }}-partition + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: partition-init +immutable: true +data: + partitionName: {{ .Values.global.adminPartitions.name }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/prometheus.yaml b/kubernetes-vault/consul/templates/prometheus.yaml new file mode 100644 index 0000000..a708708 --- /dev/null +++ b/kubernetes-vault/consul/templates/prometheus.yaml @@ -0,0 +1,488 @@ +{{- if .Values.prometheus.enabled }} +# This file is auto-generated, see addons/gen.sh +--- +# Source: prometheus/templates/server/serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + component: "server" + app: prometheus + release: prometheus + chart: prometheus-13.2.1 + heritage: Helm + name: prometheus-server + namespace: {{ .Release.Namespace }} + annotations: + {} +--- +# Source: prometheus/templates/server/cm.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + component: "server" + app: prometheus + release: prometheus + chart: prometheus-13.2.1 + heritage: Helm + name: prometheus-server + namespace: {{ .Release.Namespace }} +data: + alerting_rules.yml: | + {} + alerts: | + {} + prometheus.yml: | + global: + evaluation_interval: 1m + scrape_interval: 15s + scrape_timeout: 10s + rule_files: + - /etc/config/recording_rules.yml + - /etc/config/alerting_rules.yml + - /etc/config/rules + - /etc/config/alerts + scrape_configs: + - job_name: prometheus + static_configs: + - targets: + - localhost:9090 + - bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + job_name: kubernetes-apiservers + kubernetes_sd_configs: + - role: endpoints + relabel_configs: + - action: keep + regex: default;kubernetes;https + source_labels: + - __meta_kubernetes_namespace + - __meta_kubernetes_service_name + - __meta_kubernetes_endpoint_port_name + scheme: https + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + insecure_skip_verify: true + - bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + job_name: kubernetes-nodes + kubernetes_sd_configs: + - role: node + relabel_configs: + - action: labelmap + regex: __meta_kubernetes_node_label_(.+) + - replacement: kubernetes.default.svc:443 + target_label: __address__ + - regex: (.+) + replacement: /api/v1/nodes/$1/proxy/metrics + source_labels: + - __meta_kubernetes_node_name + target_label: __metrics_path__ + scheme: https + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + insecure_skip_verify: true + - bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + job_name: kubernetes-nodes-cadvisor + kubernetes_sd_configs: + - role: node + relabel_configs: + - action: labelmap + regex: __meta_kubernetes_node_label_(.+) + - replacement: kubernetes.default.svc:443 + target_label: __address__ + - regex: (.+) + replacement: /api/v1/nodes/$1/proxy/metrics/cadvisor + source_labels: + - __meta_kubernetes_node_name + target_label: __metrics_path__ + scheme: https + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + insecure_skip_verify: true + - job_name: kubernetes-service-endpoints + kubernetes_sd_configs: + - role: endpoints + relabel_configs: + - action: keep + regex: true + source_labels: + - __meta_kubernetes_service_annotation_prometheus_io_scrape + - action: replace + regex: (https?) + source_labels: + - __meta_kubernetes_service_annotation_prometheus_io_scheme + target_label: __scheme__ + - action: replace + regex: (.+) + source_labels: + - __meta_kubernetes_service_annotation_prometheus_io_path + target_label: __metrics_path__ + - action: replace + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + source_labels: + - __address__ + - __meta_kubernetes_service_annotation_prometheus_io_port + target_label: __address__ + - action: labelmap + regex: __meta_kubernetes_service_label_(.+) + - action: replace + source_labels: + - __meta_kubernetes_namespace + target_label: kubernetes_namespace + - action: replace + source_labels: + - __meta_kubernetes_service_name + target_label: kubernetes_name + - action: replace + source_labels: + - __meta_kubernetes_pod_node_name + target_label: kubernetes_node + - job_name: kubernetes-service-endpoints-slow + kubernetes_sd_configs: + - role: endpoints + relabel_configs: + - action: keep + regex: true + source_labels: + - __meta_kubernetes_service_annotation_prometheus_io_scrape_slow + - action: replace + regex: (https?) + source_labels: + - __meta_kubernetes_service_annotation_prometheus_io_scheme + target_label: __scheme__ + - action: replace + regex: (.+) + source_labels: + - __meta_kubernetes_service_annotation_prometheus_io_path + target_label: __metrics_path__ + - action: replace + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + source_labels: + - __address__ + - __meta_kubernetes_service_annotation_prometheus_io_port + target_label: __address__ + - action: labelmap + regex: __meta_kubernetes_service_label_(.+) + - action: replace + source_labels: + - __meta_kubernetes_namespace + target_label: kubernetes_namespace + - action: replace + source_labels: + - __meta_kubernetes_service_name + target_label: kubernetes_name + - action: replace + source_labels: + - __meta_kubernetes_pod_node_name + target_label: kubernetes_node + scrape_interval: 5m + scrape_timeout: 30s + - honor_labels: true + job_name: prometheus-pushgateway + kubernetes_sd_configs: + - role: service + relabel_configs: + - action: keep + regex: pushgateway + source_labels: + - __meta_kubernetes_service_annotation_prometheus_io_probe + - job_name: kubernetes-services + kubernetes_sd_configs: + - role: service + metrics_path: /probe + params: + module: + - http_2xx + relabel_configs: + - action: keep + regex: true + source_labels: + - __meta_kubernetes_service_annotation_prometheus_io_probe + - source_labels: + - __address__ + target_label: __param_target + - replacement: blackbox + target_label: __address__ + - source_labels: + - __param_target + target_label: instance + - action: labelmap + regex: __meta_kubernetes_service_label_(.+) + - source_labels: + - __meta_kubernetes_namespace + target_label: kubernetes_namespace + - source_labels: + - __meta_kubernetes_service_name + target_label: kubernetes_name + - job_name: kubernetes-pods + kubernetes_sd_configs: + - role: pod + relabel_configs: + - action: keep + regex: true + source_labels: + - __meta_kubernetes_pod_annotation_prometheus_io_scrape + - action: replace + regex: (https?) + source_labels: + - __meta_kubernetes_pod_annotation_prometheus_io_scheme + target_label: __scheme__ + - action: replace + regex: (.+) + source_labels: + - __meta_kubernetes_pod_annotation_prometheus_io_path + target_label: __metrics_path__ + - action: replace + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + source_labels: + - __address__ + - __meta_kubernetes_pod_annotation_prometheus_io_port + target_label: __address__ + - action: labelmap + regex: __meta_kubernetes_pod_label_(.+) + - action: replace + source_labels: + - __meta_kubernetes_namespace + target_label: kubernetes_namespace + - action: replace + source_labels: + - __meta_kubernetes_pod_name + target_label: kubernetes_pod_name + - action: drop + regex: Pending|Succeeded|Failed + source_labels: + - __meta_kubernetes_pod_phase + - job_name: kubernetes-pods-slow + kubernetes_sd_configs: + - role: pod + relabel_configs: + - action: keep + regex: true + source_labels: + - __meta_kubernetes_pod_annotation_prometheus_io_scrape_slow + - action: replace + regex: (https?) + source_labels: + - __meta_kubernetes_pod_annotation_prometheus_io_scheme + target_label: __scheme__ + - action: replace + regex: (.+) + source_labels: + - __meta_kubernetes_pod_annotation_prometheus_io_path + target_label: __metrics_path__ + - action: replace + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + source_labels: + - __address__ + - __meta_kubernetes_pod_annotation_prometheus_io_port + target_label: __address__ + - action: labelmap + regex: __meta_kubernetes_pod_label_(.+) + - action: replace + source_labels: + - __meta_kubernetes_namespace + target_label: kubernetes_namespace + - action: replace + source_labels: + - __meta_kubernetes_pod_name + target_label: kubernetes_pod_name + - action: drop + regex: Pending|Succeeded|Failed + source_labels: + - __meta_kubernetes_pod_phase + scrape_interval: 5m + scrape_timeout: 30s + recording_rules.yml: | + {} + rules: | + {} +--- +# Source: prometheus/templates/server/clusterrole.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + component: "server" + app: prometheus + release: prometheus + chart: prometheus-13.2.1 + heritage: Helm + name: prometheus-server +rules: + - apiGroups: + - "" + resources: + - nodes + - nodes/proxy + - nodes/metrics + - services + - endpoints + - pods + - ingresses + - configmaps + verbs: + - get + - list + - watch + - apiGroups: + - "extensions" + - "networking.k8s.io" + resources: + - ingresses/status + - ingresses + verbs: + - get + - list + - watch + - nonResourceURLs: + - "/metrics" + verbs: + - get +--- +# Source: prometheus/templates/server/clusterrolebinding.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + component: "server" + app: prometheus + release: prometheus + chart: prometheus-13.2.1 + heritage: Helm + name: prometheus-server +subjects: + - kind: ServiceAccount + name: prometheus-server + namespace: {{ .Release.Namespace }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: prometheus-server +--- +# Source: prometheus/templates/server/service.yaml +apiVersion: v1 +kind: Service +metadata: + labels: + component: "server" + app: prometheus + release: prometheus + chart: prometheus-13.2.1 + heritage: Helm + name: prometheus-server + namespace: {{ .Release.Namespace }} +spec: + ports: + - name: http + port: 80 + protocol: TCP + targetPort: 9090 + selector: + component: "server" + app: prometheus + release: prometheus + sessionAffinity: None + type: "ClusterIP" +--- +# Source: prometheus/templates/server/deploy.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + component: "server" + app: prometheus + release: prometheus + chart: prometheus-13.2.1 + heritage: Helm + name: prometheus-server + namespace: {{ .Release.Namespace }} +spec: + selector: + matchLabels: + component: "server" + app: prometheus + release: prometheus + replicas: 1 + template: + metadata: + annotations: + consul.hashicorp.com/connect-inject: "false" + consul.hashicorp.com/mesh-inject: "false" + labels: + component: "server" + app: prometheus + release: prometheus + chart: prometheus-13.2.1 + heritage: Helm + spec: + serviceAccountName: prometheus-server + containers: + - name: prometheus-server-configmap-reload + image: "jimmidyson/configmap-reload:v0.4.0" + imagePullPolicy: "IfNotPresent" + args: + - --volume-dir=/etc/config + - --webhook-url=http://127.0.0.1:9090/-/reload + resources: + {} + volumeMounts: + - name: config-volume + mountPath: /etc/config + readOnly: true + + - name: prometheus-server + image: "quay.io/prometheus/prometheus:v2.24.0" + imagePullPolicy: "IfNotPresent" + args: + - --storage.tsdb.retention.time=15d + - --config.file=/etc/config/prometheus.yml + - --storage.tsdb.path=/data + - --web.console.libraries=/etc/prometheus/console_libraries + - --web.console.templates=/etc/prometheus/consoles + - --web.enable-lifecycle + ports: + - containerPort: 9090 + readinessProbe: + httpGet: + path: /-/ready + port: 9090 + initialDelaySeconds: 0 + periodSeconds: 5 + timeoutSeconds: 4 + failureThreshold: 3 + successThreshold: 1 + livenessProbe: + httpGet: + path: /-/healthy + port: 9090 + initialDelaySeconds: 30 + periodSeconds: 15 + timeoutSeconds: 10 + failureThreshold: 3 + successThreshold: 1 + resources: + {} + volumeMounts: + - name: config-volume + mountPath: /etc/config + - name: storage-volume + mountPath: /data + subPath: "" + securityContext: + fsGroup: 65534 + runAsGroup: 65534 + runAsNonRoot: true + runAsUser: 65534 + terminationGracePeriodSeconds: 300 + volumes: + - name: config-volume + configMap: + name: prometheus-server + - name: storage-volume + emptyDir: + {} +{{- end }} diff --git a/kubernetes-vault/consul/templates/server-acl-init-cleanup-job.yaml b/kubernetes-vault/consul/templates/server-acl-init-cleanup-job.yaml new file mode 100644 index 0000000..3d7d6c8 --- /dev/null +++ b/kubernetes-vault/consul/templates/server-acl-init-cleanup-job.yaml @@ -0,0 +1,90 @@ +{{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} +{{- if (or $serverEnabled .Values.externalServers.enabled) }} +{{- if .Values.global.acls.manageSystemACLs }} +{{- /* See reason for this in server-acl-init-job.yaml */ -}} +{{- if eq (int .Values.server.updatePartition) 0 }} +# This job deletes the server-acl-init job once it completes successfully. +# It runs as a helm hook because it only needs to run when the server-acl-init +# Job gets recreated which only happens during an install or upgrade. +# We also utilize the helm hook-delete-policy to delete this job itself. +# We want to delete the server-acl-init job because once it runs successfully +# it's not needed and also because if it stays around then when users run +# helm upgrade with values that change the spec of the job, Kubernetes errors +# because the job spec is immutable. If the job is deleted, then a new job +# is created and there's no error. +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ template "consul.fullname" . }}-server-acl-init-cleanup + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: server-acl-init-cleanup + {{- if .Values.global.extraLabels }} + {{- toYaml .Values.global.extraLabels | nindent 4 }} + {{- end }} + annotations: + "helm.sh/hook": post-install,post-upgrade + "helm.sh/hook-weight": "0" + # If the hook fails then all that happens is we didn't delete the job. + # There's no reason for *this* job to stay around in that case so delete + # regardless of success. + "helm.sh/hook-delete-policy": hook-succeeded,hook-failed +spec: + template: + metadata: + name: {{ template "consul.fullname" . }}-server-acl-init-cleanup + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: server-acl-init-cleanup + {{- if .Values.global.extraLabels }} + {{- toYaml .Values.global.extraLabels | nindent 8 }} + {{- end }} + annotations: + "consul.hashicorp.com/connect-inject": "false" + "consul.hashicorp.com/mesh-inject": "false" + {{- if .Values.global.acls.annotations }} + {{- tpl .Values.global.acls.annotations . | nindent 8 }} + {{- end }} + spec: + restartPolicy: Never + serviceAccountName: {{ template "consul.fullname" . }}-server-acl-init-cleanup + {{- if .Values.server.containerSecurityContext.aclInit }} + securityContext: + {{- toYaml .Values.server.containerSecurityContext.aclInit | nindent 8 }} + {{- end }} + containers: + - name: server-acl-init-cleanup + image: {{ .Values.global.imageK8S }} + {{ template "consul.imagePullPolicy" . }} + {{- if not .Values.server.containerSecurityContext.aclInit }} + {{- include "consul.restrictedSecurityContext" . | nindent 10 }} + {{- end }} + command: + - consul-k8s-control-plane + args: + - delete-completed-job + - -log-level={{ default .Values.global.logLevel .Values.global.acls.logLevel }} + - -log-json={{ .Values.global.logJSON }} + - -k8s-namespace={{ .Release.Namespace }} + - {{ template "consul.fullname" . }}-server-acl-init + {{- if .Values.global.acls.resources }} + resources: + {{- toYaml .Values.global.acls.resources | nindent 12 }} + {{- end }} + {{- if .Values.global.acls.tolerations }} + tolerations: + {{ tpl .Values.global.acls.tolerations . | indent 8 | trim }} + {{- end }} + {{- if .Values.global.acls.nodeSelector }} + nodeSelector: + {{ tpl .Values.global.acls.nodeSelector . | indent 8 | trim }} + {{- end }} + {{- end }} + {{- end }} + {{- end }} diff --git a/kubernetes-vault/consul/templates/server-acl-init-cleanup-podsecuritypolicy.yaml b/kubernetes-vault/consul/templates/server-acl-init-cleanup-podsecuritypolicy.yaml new file mode 100644 index 0000000..dd5dad2 --- /dev/null +++ b/kubernetes-vault/consul/templates/server-acl-init-cleanup-podsecuritypolicy.yaml @@ -0,0 +1,40 @@ +{{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} +{{- if (or $serverEnabled .Values.externalServers.enabled) }} +{{- if .Values.global.acls.manageSystemACLs }} +{{- if .Values.global.enablePodSecurityPolicies }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "consul.fullname" . }}-server-acl-init-cleanup + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: server-acl-init-cleanup +spec: + privileged: false + # Allow core volume types. + volumes: + - 'secret' + allowPrivilegeEscalation: false + # This is redundant with non-root + disallow privilege escalation, + # but we can provide it for defense in depth. + requiredDropCapabilities: + - ALL + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' + readOnlyRootFilesystem: false + {{- end }} + {{- end }} + {{- end }} diff --git a/kubernetes-vault/consul/templates/server-acl-init-cleanup-role.yaml b/kubernetes-vault/consul/templates/server-acl-init-cleanup-role.yaml new file mode 100644 index 0000000..0a2f296 --- /dev/null +++ b/kubernetes-vault/consul/templates/server-acl-init-cleanup-role.yaml @@ -0,0 +1,28 @@ +{{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} +{{- if (or $serverEnabled .Values.externalServers.enabled) }} +{{- if .Values.global.acls.manageSystemACLs }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "consul.fullname" . }}-server-acl-init-cleanup + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: server-acl-init-cleanup +rules: + - apiGroups: ["batch"] + resources: ["jobs"] + verbs: ["get", "delete"] +{{- if .Values.global.enablePodSecurityPolicies }} + - apiGroups: ["policy"] + resources: ["podsecuritypolicies"] + resourceNames: + - {{ template "consul.fullname" . }}-server-acl-init-cleanup + verbs: + - use +{{- end }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/server-acl-init-cleanup-rolebinding.yaml b/kubernetes-vault/consul/templates/server-acl-init-cleanup-rolebinding.yaml new file mode 100644 index 0000000..268eaa5 --- /dev/null +++ b/kubernetes-vault/consul/templates/server-acl-init-cleanup-rolebinding.yaml @@ -0,0 +1,23 @@ +{{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} +{{- if (or $serverEnabled .Values.externalServers.enabled) }} +{{- if .Values.global.acls.manageSystemACLs }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "consul.fullname" . }}-server-acl-init-cleanup + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: server-acl-init-cleanup +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "consul.fullname" . }}-server-acl-init-cleanup +subjects: + - kind: ServiceAccount + name: {{ template "consul.fullname" . }}-server-acl-init-cleanup +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/server-acl-init-cleanup-serviceaccount.yaml b/kubernetes-vault/consul/templates/server-acl-init-cleanup-serviceaccount.yaml new file mode 100644 index 0000000..604e6d7 --- /dev/null +++ b/kubernetes-vault/consul/templates/server-acl-init-cleanup-serviceaccount.yaml @@ -0,0 +1,22 @@ +{{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} +{{- if (or $serverEnabled .Values.externalServers.enabled) }} +{{- if .Values.global.acls.manageSystemACLs }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "consul.fullname" . }}-server-acl-init-cleanup + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: server-acl-init-cleanup +{{- with .Values.global.imagePullSecrets }} +imagePullSecrets: +{{- range . }} + - name: {{ .name }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/server-acl-init-job.yaml b/kubernetes-vault/consul/templates/server-acl-init-job.yaml new file mode 100644 index 0000000..0156c60 --- /dev/null +++ b/kubernetes-vault/consul/templates/server-acl-init-job.yaml @@ -0,0 +1,350 @@ +{{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} +{{- if (and $serverEnabled .Values.externalServers.enabled) }}{{ fail "only one of server.enabled or externalServers.enabled can be set" }}{{ end -}} +{{- if (or $serverEnabled .Values.externalServers.enabled) }} +{{- if and .Values.global.acls.createReplicationToken (not .Values.global.acls.manageSystemACLs) }}{{ fail "if global.acls.createReplicationToken is true, global.acls.manageSystemACLs must be true" }}{{ end -}} +{{- if .Values.global.bootstrapACLs }}{{ fail "global.bootstrapACLs was removed, use global.acls.manageSystemACLs instead" }}{{ end -}} +{{- if .Values.global.acls.manageSystemACLs }} +{{- if or (and .Values.global.acls.bootstrapToken.secretName (not .Values.global.acls.bootstrapToken.secretKey)) (and .Values.global.acls.bootstrapToken.secretKey (not .Values.global.acls.bootstrapToken.secretName))}}{{ fail "both global.acls.bootstrapToken.secretKey and global.acls.bootstrapToken.secretName must be set if one of them is provided" }}{{ end -}} +{{- if or (and .Values.global.acls.replicationToken.secretName (not .Values.global.acls.replicationToken.secretKey)) (and .Values.global.acls.replicationToken.secretKey (not .Values.global.acls.replicationToken.secretName))}}{{ fail "both global.acls.replicationToken.secretKey and global.acls.replicationToken.secretName must be set if one of them is provided" }}{{ end -}} +{{- if (and .Values.global.secretsBackend.vault.enabled (and (not .Values.global.acls.bootstrapToken.secretName) (not .Values.global.acls.replicationToken.secretName ))) }}{{fail "global.acls.bootstrapToken or global.acls.replicationToken must be provided when global.secretsBackend.vault.enabled and global.acls.manageSystemACLs are true" }}{{ end -}} +{{ template "consul.validateRequiredCloudSecretsExist" . }} +{{ template "consul.validateCloudSecretKeys" . }} +{{- if (and .Values.global.secretsBackend.vault.enabled (not .Values.global.secretsBackend.vault.manageSystemACLsRole)) }}{{fail "global.secretsBackend.vault.manageSystemACLsRole is required when global.secretsBackend.vault.enabled and global.acls.manageSystemACLs are true" }}{{ end -}} + {{- /* We don't render this job when server.updatePartition > 0 because that + means a server rollout is in progress and this job won't complete unless + the rollout is finished (which won't happen until the partition is 0). + If we ran it in this case, then the job would not complete which would cause + the server-acl-init-cleanup hook to run indefinitely which would cause the + helm upgrade command to hang. +*/ -}} +{{- if eq (int .Values.server.updatePartition) 0 }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ template "consul.fullname" . }}-server-acl-init + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: server-acl-init + {{- if .Values.global.extraLabels }} + {{- toYaml .Values.global.extraLabels | nindent 4 }} + {{- end }} +spec: + template: + metadata: + name: {{ template "consul.fullname" . }}-server-acl-init + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: server-acl-init + {{- if .Values.global.extraLabels }} + {{- toYaml .Values.global.extraLabels | nindent 8 }} + {{- end }} + annotations: + "consul.hashicorp.com/connect-inject": "false" + "consul.hashicorp.com/mesh-inject": "false" + {{- if .Values.global.acls.annotations }} + {{- tpl .Values.global.acls.annotations . | nindent 8 }} + {{- end }} + {{- if .Values.global.argocd.enabled }} + "argocd.argoproj.io/hook": "Sync" + "argocd.argoproj.io/hook-delete-policy": "HookSucceeded" + {{- end }} + {{- if .Values.global.secretsBackend.vault.enabled }} + + {{- /* Run the Vault agent as both an init container and sidecar. + The Vault agent sidecar is needed when server-acl-init bootstraps ACLs + and writes the bootstrap token back to Vault. + * agent-pre-populate: true - Run the Vault agent init container. + * agent-pre-populate-only: false - Also, run the Vault agent sidecar. + * agent-cache-enable: true - Enable the Agent cache listener. + * agent-cache-listener-port: 8200 - (optional) Listen on 127.0.0.1:8200. + * agent-enable-quit: true - Enable a "quit" endpoint. server-acl-init + tells the Vault agent to stop (without this the Job will not complete). + */}} + "vault.hashicorp.com/agent-pre-populate": "true" + "vault.hashicorp.com/agent-pre-populate-only": "false" + "vault.hashicorp.com/agent-cache-enable": "true" + "vault.hashicorp.com/agent-cache-listener-port": "8200" + "vault.hashicorp.com/agent-enable-quit": "true" + "vault.hashicorp.com/agent-inject": "true" + {{- if .Values.global.acls.partitionToken.secretName }} + {{- with .Values.global.acls.partitionToken }} + "vault.hashicorp.com/agent-inject-secret-partition-token": "{{ .secretName }}" + "vault.hashicorp.com/agent-inject-template-partition-token": {{ template "consul.vaultSecretTemplate" . }} + {{- end }} + {{- end }} + {{- if .Values.global.tls.enabled }} + "vault.hashicorp.com/agent-inject-secret-serverca.crt": {{ .Values.global.tls.caCert.secretName }} + "vault.hashicorp.com/agent-inject-template-serverca.crt": {{ template "consul.serverTLSCATemplate" . }} + {{- end }} + {{- if .Values.global.secretsBackend.vault.manageSystemACLsRole }} + "vault.hashicorp.com/role": {{ .Values.global.secretsBackend.vault.manageSystemACLsRole }} + {{- else if .Values.global.tls.enabled }} + "vault.hashicorp.com/role": {{ .Values.global.secretsBackend.vault.consulCARole }} + {{- end }} + {{- if and .Values.global.secretsBackend.vault.ca.secretName .Values.global.secretsBackend.vault.ca.secretKey }} + "vault.hashicorp.com/agent-extra-secret": "{{ .Values.global.secretsBackend.vault.ca.secretName }}" + "vault.hashicorp.com/ca-cert": "/vault/custom/{{ .Values.global.secretsBackend.vault.ca.secretKey }}" + {{- end }} + {{- if .Values.global.acls.replicationToken.secretName }} + "vault.hashicorp.com/agent-inject-secret-replication-token": "{{ .Values.global.acls.replicationToken.secretName }}" + "vault.hashicorp.com/agent-inject-template-replication-token": {{ template "consul.vaultReplicationTokenTemplate" . }} + {{- end }} + {{- if .Values.global.secretsBackend.vault.agentAnnotations }} + {{ tpl .Values.global.secretsBackend.vault.agentAnnotations . | nindent 8 | trim }} + {{- end }} + {{- if (and (.Values.global.secretsBackend.vault.vaultNamespace) (not (hasKey (default "" .Values.global.secretsBackend.vault.agentAnnotations | fromYaml) "vault.hashicorp.com/namespace")))}} + "vault.hashicorp.com/namespace": "{{ .Values.global.secretsBackend.vault.vaultNamespace }}" + {{- end }} + {{- end }} + spec: + restartPolicy: Never + serviceAccountName: {{ template "consul.fullname" . }}-server-acl-init + {{- if .Values.server.containerSecurityContext.aclInit }} + securityContext: + {{- toYaml .Values.server.containerSecurityContext.aclInit | nindent 8 }} + {{- end }} + {{- if (or .Values.global.tls.enabled .Values.global.acls.replicationToken.secretName .Values.global.acls.bootstrapToken.secretName) }} + volumes: + {{- if and .Values.global.tls.enabled (not .Values.global.secretsBackend.vault.enabled) }} + {{- if not (and .Values.externalServers.enabled .Values.externalServers.useSystemRoots) }} + - name: consul-ca-cert + secret: + {{- if .Values.global.tls.caCert.secretName }} + secretName: {{ .Values.global.tls.caCert.secretName }} + {{- else }} + secretName: {{ template "consul.fullname" . }}-ca-cert + {{- end }} + items: + - key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }} + path: tls.crt + {{- end }} + {{- end }} + {{- if and .Values.global.acls.replicationToken.secretName (not .Values.global.secretsBackend.vault.enabled) }} + - name: acl-replication-token + secret: + secretName: {{ .Values.global.acls.replicationToken.secretName }} + items: + - key: {{ .Values.global.acls.replicationToken.secretKey }} + path: acl-replication-token + {{- end }} + {{- end }} + containers: + - name: server-acl-init-job + image: {{ .Values.global.imageK8S }} + {{ template "consul.imagePullPolicy" . }} + {{- if not .Values.server.containerSecurityContext.aclInit }} + {{- include "consul.restrictedSecurityContext" . | nindent 8 }} + {{- end }} + env: + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + # Extract the Vault namespace from the Vault agent annotations. + {{- if .Values.global.secretsBackend.vault.enabled }} + {{- if and (.Values.global.secretsBackend.vault.agentAnnotations) (hasKey (default "" .Values.global.secretsBackend.vault.agentAnnotations | fromYaml) "vault.hashicorp.com/namespace") }} + - name: VAULT_NAMESPACE + value: {{ get (tpl .Values.global.secretsBackend.vault.agentAnnotations . | fromYaml) "vault.hashicorp.com/namespace" }} + {{- else if .Values.global.secretsBackend.vault.vaultNamespace }} + - name: VAULT_NAMESPACE + value: {{ .Values.global.secretsBackend.vault.vaultNamespace }} + {{- end }} + {{- end }} + {{- include "consul.consulK8sConsulServerEnvVars" . | nindent 8 }} + {{- if (or .Values.global.tls.enabled .Values.global.acls.replicationToken.secretName .Values.global.acls.bootstrapToken.secretName) }} + volumeMounts: + {{- if and .Values.global.tls.enabled (not .Values.global.secretsBackend.vault.enabled) }} + {{- if not (and .Values.externalServers.enabled .Values.externalServers.useSystemRoots) }} + - name: consul-ca-cert + mountPath: /consul/tls/ca + readOnly: true + {{- end }} + {{- end }} + {{- if and .Values.global.acls.replicationToken.secretName (not .Values.global.secretsBackend.vault.enabled) }} + - name: acl-replication-token + mountPath: /consul/acl/tokens + readOnly: true + {{- end }} + {{- end }} + command: + - "/bin/sh" + - "-ec" + - | + CONSUL_FULLNAME="{{template "consul.fullname" . }}" + + exec consul-k8s-control-plane server-acl-init \ + -log-level={{ default .Values.global.logLevel .Values.global.acls.logLevel}} \ + -log-json={{ .Values.global.logJSON }} \ + -resource-prefix=${CONSUL_FULLNAME} \ + -k8s-namespace={{ .Release.Namespace }} \ + -set-server-tokens={{ $serverEnabled }} \ + {{- if .Values.global.secretsBackend.vault.enabled }} + -secrets-backend=vault \ + {{- else }} + -secrets-backend=kubernetes \ + {{- end }} + + {{- if (mustHas "resource-apis" .Values.global.experiments) }} + -enable-resource-apis=true \ + {{- end }} + + {{- if .Values.global.acls.bootstrapToken.secretName }} + -bootstrap-token-secret-name={{ .Values.global.acls.bootstrapToken.secretName }} \ + -bootstrap-token-secret-key={{ .Values.global.acls.bootstrapToken.secretKey }} \ + {{- end }} + + {{- if .Values.syncCatalog.enabled }} + -sync-catalog=true \ + {{- if .Values.syncCatalog.consulNodeName }} + -sync-consul-node-name={{ .Values.syncCatalog.consulNodeName }} \ + {{- end }} + {{- end }} + + {{- if .Values.global.peering.enabled }} + -enable-peering=true \ + {{- end }} + {{- if (or (and (ne (.Values.dns.enabled | toString) "-") .Values.dns.enabled) (and (eq (.Values.dns.enabled | toString) "-") .Values.connectInject.transparentProxy.defaultEnabled)) }} + -allow-dns=true \ + {{- end }} + + {{- if (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled)) }} + -connect-inject=true \ + {{- end }} + {{- if and .Values.externalServers.enabled .Values.externalServers.k8sAuthMethodHost }} + -auth-method-host={{ .Values.externalServers.k8sAuthMethodHost }} \ + {{- end }} + + {{- if .Values.global.federation.k8sAuthMethodHost }} + -auth-method-host={{ .Values.global.federation.k8sAuthMethodHost }} \ + {{- end }} + + {{- if .Values.meshGateway.enabled }} + -mesh-gateway=true \ + {{- end }} + + {{- if .Values.ingressGateways.enabled }} + {{- if .Values.global.enableConsulNamespaces }} + {{- $root := . }} + {{- range .Values.ingressGateways.gateways }} + {{- if (or $root.Values.ingressGateways.defaults.consulNamespace .consulNamespace) }} + -ingress-gateway-name="{{ .name }}.{{ (default $root.Values.ingressGateways.defaults.consulNamespace .consulNamespace) }}" \ + {{- else }} + -ingress-gateway-name="{{ .name }}" \ + {{- end }} + {{- end }} + {{- else }} + {{- range .Values.ingressGateways.gateways }} + -ingress-gateway-name="{{ .name }}" \ + {{- end }} + {{- end }} + {{- end }} + + {{- if .Values.terminatingGateways.enabled }} + {{- if .Values.global.enableConsulNamespaces }} + {{- $root := . }} + {{- range .Values.terminatingGateways.gateways }} + {{- if (or $root.Values.terminatingGateways.defaults.consulNamespace .consulNamespace) }} + -terminating-gateway-name="{{ .name }}.{{ (default $root.Values.terminatingGateways.defaults.consulNamespace .consulNamespace) }}" \ + {{- else }} + -terminating-gateway-name="{{ .name }}" \ + {{- end }} + {{- end }} + {{- else }} + {{- range .Values.terminatingGateways.gateways }} + -terminating-gateway-name="{{ .name }}" \ + {{- end }} + {{- end }} + {{- end }} + + {{- if .Values.connectInject.aclBindingRuleSelector }} + -acl-binding-rule-selector={{ .Values.connectInject.aclBindingRuleSelector }} \ + {{- end }} + + {{- if (and .Values.global.enterpriseLicense.secretName .Values.global.enterpriseLicense.secretKey) }} + -create-enterprise-license-token=true \ + {{- end }} + + {{- if (and (not .Values.global.metrics.datadog.dogstatsd.enabled) .Values.global.metrics.datadog.enabled .Values.global.acls.manageSystemACLs) }} + -create-dd-agent-token=true \ + {{- end }} + + {{- if .Values.server.snapshotAgent.enabled }} + -snapshot-agent=true \ + {{- end }} + + {{- if not (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} + -client=false \ + {{- end }} + + {{- if .Values.global.acls.createReplicationToken }} + -create-acl-replication-token=true \ + {{- end }} + + {{- if .Values.global.federation.enabled }} + -federation=true \ + {{- end }} + + {{- if .Values.global.acls.replicationToken.secretName }} + {{- if .Values.global.secretsBackend.vault.enabled }} + -acl-replication-token-file=/vault/secrets/replication-token \ + {{- else }} + -acl-replication-token-file=/consul/acl/tokens/acl-replication-token \ + {{- end }} + {{- end }} + {{- if and .Values.global.secretsBackend.vault.enabled .Values.global.acls.partitionToken.secretName }} + -partition-token-file=/vault/secrets/partition-token \ + {{- end }} + + {{- if .Values.global.enableConsulNamespaces }} + -enable-namespaces=true \ + {{- /* syncCatalog must be enabled to set sync flags */}} + {{- if (or (and (ne (.Values.syncCatalog.enabled | toString) "-") .Values.syncCatalog.enabled) (and (eq (.Values.syncCatalog.enabled | toString) "-") .Values.global.enabled)) }} + {{- if .Values.syncCatalog.consulNamespaces.consulDestinationNamespace }} + -consul-sync-destination-namespace={{ .Values.syncCatalog.consulNamespaces.consulDestinationNamespace }} \ + {{- end }} + {{- if .Values.syncCatalog.consulNamespaces.mirroringK8S }} + -enable-sync-k8s-namespace-mirroring=true \ + {{- if .Values.syncCatalog.consulNamespaces.mirroringK8SPrefix }} + -sync-k8s-namespace-mirroring-prefix={{ .Values.syncCatalog.consulNamespaces.mirroringK8SPrefix }} \ + {{- end }} + {{- end }} + {{- end }} + + {{- /* connectInject must be enabled to set inject flags */}} + {{- if (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled)) }} + {{- if .Values.connectInject.consulNamespaces.consulDestinationNamespace }} + -consul-inject-destination-namespace={{ .Values.connectInject.consulNamespaces.consulDestinationNamespace }} \ + {{- end }} + {{- if .Values.connectInject.consulNamespaces.mirroringK8S }} + -enable-inject-k8s-namespace-mirroring=true \ + {{- if .Values.connectInject.consulNamespaces.mirroringK8SPrefix }} + -inject-k8s-namespace-mirroring-prefix={{ .Values.connectInject.consulNamespaces.mirroringK8SPrefix }} \ + {{- end }} + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.global.acls.resources }} + resources: + {{- toYaml .Values.global.acls.resources | nindent 10 }} + {{- end }} + {{- if .Values.global.acls.tolerations }} + tolerations: + {{ tpl .Values.global.acls.tolerations . | indent 8 | trim }} + {{- end }} + {{- if .Values.global.acls.nodeSelector }} + nodeSelector: + {{ tpl .Values.global.acls.nodeSelector . | indent 8 | trim }} + {{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/server-acl-init-podsecuritypolicy.yaml b/kubernetes-vault/consul/templates/server-acl-init-podsecuritypolicy.yaml new file mode 100644 index 0000000..9bf93e2 --- /dev/null +++ b/kubernetes-vault/consul/templates/server-acl-init-podsecuritypolicy.yaml @@ -0,0 +1,41 @@ +{{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} +{{- if (or $serverEnabled .Values.externalServers.enabled) }} +{{- if .Values.global.acls.manageSystemACLs }} +{{- if .Values.global.enablePodSecurityPolicies }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "consul.fullname" . }}-server-acl-init + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: server-acl-init +spec: + privileged: false + # Allow core volume types. + volumes: + - 'secret' + - 'emptyDir' + allowPrivilegeEscalation: false + # This is redundant with non-root + disallow privilege escalation, + # but we can provide it for defense in depth. + requiredDropCapabilities: + - ALL + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' + readOnlyRootFilesystem: false + {{- end }} + {{- end }} + {{- end }} diff --git a/kubernetes-vault/consul/templates/server-acl-init-role.yaml b/kubernetes-vault/consul/templates/server-acl-init-role.yaml new file mode 100644 index 0000000..eb7b6a9 --- /dev/null +++ b/kubernetes-vault/consul/templates/server-acl-init-role.yaml @@ -0,0 +1,38 @@ +{{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} +{{- if (or $serverEnabled .Values.externalServers.enabled) }} +{{- if .Values.global.acls.manageSystemACLs }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "consul.fullname" . }}-server-acl-init + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: server-acl-init +rules: +- apiGroups: [ "" ] + resources: + - secrets + verbs: + - create + - get +- apiGroups: [ "" ] + resources: + - serviceaccounts + resourceNames: + - {{ template "consul.fullname" . }}-auth-method + verbs: + - get +{{- if .Values.global.enablePodSecurityPolicies }} +- apiGroups: [ "policy" ] + resources: [ "podsecuritypolicies" ] + resourceNames: + - {{ template "consul.fullname" . }}-server-acl-init + verbs: + - use +{{- end }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/server-acl-init-rolebinding.yaml b/kubernetes-vault/consul/templates/server-acl-init-rolebinding.yaml new file mode 100644 index 0000000..fda4726 --- /dev/null +++ b/kubernetes-vault/consul/templates/server-acl-init-rolebinding.yaml @@ -0,0 +1,23 @@ +{{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} +{{- if (or $serverEnabled .Values.externalServers.enabled) }} +{{- if .Values.global.acls.manageSystemACLs }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "consul.fullname" . }}-server-acl-init + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: server-acl-init +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "consul.fullname" . }}-server-acl-init +subjects: + - kind: ServiceAccount + name: {{ template "consul.fullname" . }}-server-acl-init +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/server-acl-init-serviceaccount.yaml b/kubernetes-vault/consul/templates/server-acl-init-serviceaccount.yaml new file mode 100644 index 0000000..c0e257d --- /dev/null +++ b/kubernetes-vault/consul/templates/server-acl-init-serviceaccount.yaml @@ -0,0 +1,22 @@ +{{- $serverEnabled := (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) -}} +{{- if (or $serverEnabled .Values.externalServers.enabled) }} +{{- if .Values.global.acls.manageSystemACLs }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "consul.fullname" . }}-server-acl-init + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: server-acl-init +{{- with .Values.global.imagePullSecrets }} +imagePullSecrets: +{{- range . }} + - name: {{ .name }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/server-clusterrole.yaml b/kubernetes-vault/consul/templates/server-clusterrole.yaml new file mode 100644 index 0000000..c22f562 --- /dev/null +++ b/kubernetes-vault/consul/templates/server-clusterrole.yaml @@ -0,0 +1,16 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "consul.fullname" . }}-server + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: server +rules: +- apiGroups: [""] + resources: ["nodes"] + verbs: + - get diff --git a/kubernetes-vault/consul/templates/server-clusterrolebinding.yaml b/kubernetes-vault/consul/templates/server-clusterrolebinding.yaml new file mode 100644 index 0000000..854fda8 --- /dev/null +++ b/kubernetes-vault/consul/templates/server-clusterrolebinding.yaml @@ -0,0 +1,18 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "consul.fullname" . }}-server + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: server +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "consul.fullname" . }}-server +subjects: +- kind: ServiceAccount + name: {{ template "consul.fullname" . }}-server + namespace: {{ .Release.Namespace }} diff --git a/kubernetes-vault/consul/templates/server-config-configmap.yaml b/kubernetes-vault/consul/templates/server-config-configmap.yaml new file mode 100644 index 0000000..8c74364 --- /dev/null +++ b/kubernetes-vault/consul/templates/server-config-configmap.yaml @@ -0,0 +1,220 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if (not (or (eq .Values.server.limits.requestLimits.mode "disabled") (eq .Values.server.limits.requestLimits.mode "permissive") (eq .Values.server.limits.requestLimits.mode "enforce"))) }}{{fail "server.limits.requestLimits.mode must be one of the following values: disabled, permissive, and enforce." }}{{ end -}} +{{- if and .Values.server.auditLogs.enabled (not .Values.global.acls.manageSystemACLs) }}{{fail "ACLs must be enabled inorder to configure audit logs"}}{{ end -}} +# StatefulSet to run the actual Consul server cluster. +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "consul.fullname" . }}-server-config + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: server +data: + server.json: | + { + {{- if and .Values.global.secretsBackend.vault.enabled }} + "auto_reload_config": true, + {{- end }} + "bind_addr": "0.0.0.0", + "bootstrap_expect": {{ if .Values.server.bootstrapExpect }}{{ .Values.server.bootstrapExpect }}{{ else }}{{ .Values.server.replicas }}{{ end }}, + "client_addr": "0.0.0.0", + "connect": { + "enabled": {{ .Values.server.connect }} + }, + "datacenter": "{{ .Values.global.datacenter }}", + "data_dir": "/consul/data", + {{- if .Values.server.logLevel }} + "log_level": "{{ .Values.server.logLevel | upper }}", + {{- end }} + "enable_debug": {{ .Values.server.enableAgentDebug }}, + "domain": "{{ .Values.global.domain }}", + "limits": { + "request_limits": { + "mode": "{{ .Values.server.limits.requestLimits.mode }}", + "read_rate": {{ .Values.server.limits.requestLimits.readRate }}, + "write_rate": {{ .Values.server.limits.requestLimits.writeRate }} + } + }, + "ports": { + {{- if not .Values.global.tls.enabled }} + "grpc": 8502, + "grpc_tls": -1, + {{- end }} + {{- if .Values.global.tls.enabled }} + "grpc": -1, + "grpc_tls": 8502, + {{- end }} + "serf_lan": {{ .Values.server.ports.serflan.port }} + }, + "recursors": {{ .Values.global.recursors | toJson }}, + "retry_join": ["{{template "consul.fullname" . }}-server.{{ .Release.Namespace }}.svc:{{ .Values.server.ports.serflan.port }}"], + {{- if .Values.global.peering.enabled }} + "peering": { + "enabled": true + }, + {{- end }} + "server": true, + "leave_on_terminate": true, + "autopilot": { + "min_quorum": {{ template "consul.server.autopilotMinQuorum" . }}, + "disable_upgrade_migration": true + } + } + {{- $vaultConnectCAEnabled := and .Values.global.secretsBackend.vault.connectCA.address .Values.global.secretsBackend.vault.connectCA.rootPKIPath .Values.global.secretsBackend.vault.connectCA.intermediatePKIPath -}} + {{- if and .Values.global.secretsBackend.vault.enabled $vaultConnectCAEnabled }} + {{- with .Values.global.secretsBackend.vault }} + connect-ca-config.json: | + { + "connect": [ + { + "ca_config": [ + { + "address": "{{ .connectCA.address }}", + {{- if and .ca.secretName .ca.secretKey }} + "ca_file": "/consul/vault-ca/tls.crt", + {{- end }} + "intermediate_pki_path": "{{ .connectCA.intermediatePKIPath }}", + {{- if (and (.vaultNamespace) (not (contains "namespace" (default "" .connectCA.additionalConfig)))) }} + "namespace": "{{ .vaultNamespace }}", + {{- end }} + "root_pki_path": "{{ .connectCA.rootPKIPath }}", + "auth_method": { + "type": "kubernetes", + "mount_path": "{{ .connectCA.authMethodPath }}", + "params": { + "role": "{{ .consulServerRole }}" + } + } + } + ], + "ca_provider": "vault" + } + ] + } + {{- if .connectCA.additionalConfig }} + additional-connect-ca-config.json: | +{{ tpl .connectCA.additionalConfig $ | trimAll "\"" | indent 4 }} + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.global.acls.manageSystemACLs }} + acl-config.json: |- + { + "acl": { + "enabled": true, + "default_policy": "deny", + "down_policy": "extend-cache", + {{- if (and .Values.global.acls.replicationToken.secretName .Values.global.acls.replicationToken.secretKey) }} + "enable_token_replication": true, + {{- end }} + "enable_token_persistence": true + } + } + {{- end }} + {{- if .Values.global.tls.enabled }} + tls-config.json: |- + { + "tls": { + {{- if .Values.global.tls.verify }} + "internal_rpc": { + "verify_incoming": true, + "verify_server_hostname": true + }, + "grpc": { + "verify_incoming": false + }, + {{- end }} + "defaults": { + {{- if .Values.global.tls.verify }} + "verify_outgoing": true, + {{- end }} + {{- if .Values.global.secretsBackend.vault.enabled }} + "ca_file": "/vault/secrets/serverca.crt", + "cert_file": "/vault/secrets/servercert.crt", + "key_file": "/vault/secrets/servercert.key" + {{- else }} + "ca_file": "/consul/tls/ca/tls.crt", + "cert_file": "/consul/tls/server/tls.crt", + "key_file": "/consul/tls/server/tls.key" + {{- end }} + } + }, + {{- if .Values.global.tls.enableAutoEncrypt }} + "auto_encrypt": { + "allow_tls": true + }, + {{- end }} + "ports": { + {{- if .Values.global.tls.httpsOnly }} + "http": -1, + {{- end }} + "https": 8501 + } + } + {{- end }} + {{- if .Values.ui.enabled }} + ui-config.json: |- + { + "ui_config": { + {{- if (or (eq "true" (.Values.ui.metrics.enabled | toString) ) (and .Values.global.metrics.enabled (eq "-" (.Values.ui.metrics.enabled | toString)))) }} + "metrics_provider": "{{ .Values.ui.metrics.provider }}", + "metrics_proxy": { + "base_url": "{{ .Values.ui.metrics.baseURL }}" + }, + {{- end }} + {{- if .Values.ui.dashboardURLTemplates.service }} + "dashboard_url_templates": { + "service": "{{ .Values.ui.dashboardURLTemplates.service }}" + }, + {{- end }} + "enabled": true + } + } + {{- end }} + central-config.json: |- + { + "enable_central_service_config": true + } + {{- if .Values.global.federation.enabled }} + federation-config.json: |- + { + "primary_datacenter": "{{ .Values.global.federation.primaryDatacenter }}", + "primary_gateways": {{ .Values.global.federation.primaryGateways | toJson }}, + "connect": { + "enable_mesh_gateway_wan_federation": true + } + } + {{- end }} + {{- if (and .Values.global.metrics.enabled .Values.global.metrics.enableAgentMetrics) }} + telemetry-config.json: |- + { + "telemetry": { + "prometheus_retention_time": "{{ .Values.global.metrics.agentMetricsRetentionTime }}", + "disable_hostname": {{ .Values.global.metrics.disableAgentHostName }},{{ template "consul.prefixFilter" . }} + "enable_host_metrics": {{ .Values.global.metrics.enableHostMetrics }}{{- if .Values.global.metrics.datadog.dogstatsd.enabled }},{{ template "consul.dogstatsdAaddressInfo" . }} + {{- if .Values.global.metrics.datadog.dogstatsd.enabled }} + "dogstatsd_tags": {{ .Values.global.metrics.datadog.dogstatsd.dogstatsdTags | toJson }} + {{- end }} + {{- end }} + } + } + {{- end }} + {{- if and .Values.server.auditLogs.enabled .Values.global.acls.manageSystemACLs }} + audit-logging.json: |- + { + "audit": { + "enabled": true, + "sink": { + {{- range $index, $element := .Values.server.auditLogs.sinks }} + {{- if ne $index 0 }},{{end}} + "{{ get $element "name" }}": {{ omit $element "name" | toJson }} + {{- end }} + } + } + } + {{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/server-disruptionbudget.yaml b/kubernetes-vault/consul/templates/server-disruptionbudget.yaml new file mode 100644 index 0000000..56805ed --- /dev/null +++ b/kubernetes-vault/consul/templates/server-disruptionbudget.yaml @@ -0,0 +1,26 @@ +{{- if (and .Values.server.disruptionBudget.enabled (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled))) }} +# PodDisruptionBudget to prevent degrading the server cluster through +# voluntary cluster changes. +{{- if .Capabilities.APIVersions.Has "policy/v1/PodDisruptionBudget" }} +apiVersion: policy/v1 +{{- else }} +apiVersion: policy/v1beta1 +{{- end }} +kind: PodDisruptionBudget +metadata: + name: {{ template "consul.fullname" . }}-server + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: server +spec: + maxUnavailable: {{ template "consul.server.pdb.maxUnavailable" . }} + selector: + matchLabels: + app: {{ template "consul.name" . }} + release: "{{ .Release.Name }}" + component: server +{{- end }} diff --git a/kubernetes-vault/consul/templates/server-podsecuritypolicy.yaml b/kubernetes-vault/consul/templates/server-podsecuritypolicy.yaml new file mode 100644 index 0000000..09e8d75 --- /dev/null +++ b/kubernetes-vault/consul/templates/server-podsecuritypolicy.yaml @@ -0,0 +1,53 @@ +{{- if (and .Values.global.enablePodSecurityPolicies (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled))) }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "consul.fullname" . }}-server + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: server +spec: + privileged: false + # Required to prevent escalations to root. + allowPrivilegeEscalation: false + # This is redundant with non-root + disallow privilege escalation, + # but we can provide it for defense in depth. + requiredDropCapabilities: + - ALL + # Allow core volume types. + volumes: + - 'configMap' + - 'emptyDir' + - 'projected' + - 'secret' + - 'downwardAPI' + - 'persistentVolumeClaim' + hostNetwork: false + hostPorts: + {{- if .Values.server.exposeGossipAndRPCPorts }} + - min: 8300 + max: 8300 + - min: {{ .Values.server.ports.serflan.port }} + max: {{ .Values.server.ports.serflan.port }} + - min: 8302 + max: 8302 + - min: 8502 + max: 8502 + {{- end }} + hostIPC: false + hostPID: false + runAsUser: + # Require the container to run without root privileges. + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' + readOnlyRootFilesystem: false +{{- end }} diff --git a/kubernetes-vault/consul/templates/server-role.yaml b/kubernetes-vault/consul/templates/server-role.yaml new file mode 100644 index 0000000..202518b --- /dev/null +++ b/kubernetes-vault/consul/templates/server-role.yaml @@ -0,0 +1,34 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "consul.fullname" . }}-server + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: server +{{- if (or (and .Values.global.openshift.enabled .Values.server.exposeGossipAndRPCPorts) .Values.global.enablePodSecurityPolicies) }} +rules: +{{- if .Values.global.enablePodSecurityPolicies }} +- apiGroups: ["policy"] + resources: ["podsecuritypolicies"] + resourceNames: + - {{ template "consul.fullname" . }}-server + verbs: + - use +{{- end }} +{{- if (and .Values.global.openshift.enabled .Values.server.exposeGossipAndRPCPorts ) }} +- apiGroups: ["security.openshift.io"] + resources: ["securitycontextconstraints"] + resourceNames: + - {{ template "consul.fullname" . }}-server + verbs: + - use +{{- end }} +{{- else}} +rules: [] +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/server-rolebinding.yaml b/kubernetes-vault/consul/templates/server-rolebinding.yaml new file mode 100644 index 0000000..8ab705d --- /dev/null +++ b/kubernetes-vault/consul/templates/server-rolebinding.yaml @@ -0,0 +1,20 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "consul.fullname" . }}-server + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: server +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "consul.fullname" . }}-server +subjects: + - kind: ServiceAccount + name: {{ template "consul.fullname" . }}-server +{{- end }} diff --git a/kubernetes-vault/consul/templates/server-securitycontextconstraints.yaml b/kubernetes-vault/consul/templates/server-securitycontextconstraints.yaml new file mode 100644 index 0000000..8edd784 --- /dev/null +++ b/kubernetes-vault/consul/templates/server-securitycontextconstraints.yaml @@ -0,0 +1,49 @@ +{{- if (and .Values.global.openshift.enabled .Values.server.exposeGossipAndRPCPorts (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled))) }} +apiVersion: security.openshift.io/v1 +kind: SecurityContextConstraints +metadata: + name: {{ template "consul.fullname" . }}-server + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: server + annotations: + kubernetes.io/description: {{ template "consul.fullname" . }}-server are the security context constraints required + to run the consul server. +allowHostPorts: true +allowHostDirVolumePlugin: false +allowHostIPC: false +allowHostPID: false +allowHostNetwork: false +allowPrivilegeEscalation: false +allowPrivilegedContainer: false +allowedCapabilities: null +defaultAddCapabilities: null +fsGroup: + type: MustRunAs +groups: [] +priority: null +readOnlyRootFilesystem: false +requiredDropCapabilities: +- KILL +- MKNOD +- SETUID +- SETGID +runAsUser: + type: MustRunAsRange +seLinuxContext: + type: MustRunAs +supplementalGroups: + type: MustRunAs +users: [] +volumes: +- configMap +- downwardAPI +- emptyDir +- persistentVolumeClaim +- projected +- secret +{{- end -}} diff --git a/kubernetes-vault/consul/templates/server-service.yaml b/kubernetes-vault/consul/templates/server-service.yaml new file mode 100644 index 0000000..a392f0e --- /dev/null +++ b/kubernetes-vault/consul/templates/server-service.yaml @@ -0,0 +1,72 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +# Headless service for Consul server DNS entries. This service should only +# point to Consul servers. For access to an agent, one should assume that +# the agent is installed locally on the node and the NODE_IP should be used. +# If the node can't run a Consul agent, then this service can be used to +# communicate directly to a server agent. +apiVersion: v1 +kind: Service +metadata: + name: {{ template "consul.fullname" . }}-server + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: server + annotations: + {{- if .Values.server.service.annotations }} + {{ tpl .Values.server.service.annotations . | nindent 4 | trim }} + {{- end }} +spec: + clusterIP: None + # We want the servers to become available even if they're not ready + # since this DNS is also used for join operations. + publishNotReadyAddresses: true + ports: + {{- if (or (not .Values.global.tls.enabled) (not .Values.global.tls.httpsOnly)) }} + - name: http + port: 8500 + targetPort: 8500 + {{- end }} + {{- if .Values.global.tls.enabled }} + - name: https + port: 8501 + targetPort: 8501 + {{- end }} + - name: grpc + port: 8502 + targetPort: 8502 + - name: serflan-tcp + protocol: "TCP" + port: 8301 + targetPort: 8301 + - name: serflan-udp + protocol: "UDP" + port: 8301 + targetPort: 8301 + - name: serfwan-tcp + protocol: "TCP" + port: 8302 + targetPort: 8302 + - name: serfwan-udp + protocol: "UDP" + port: 8302 + targetPort: 8302 + - name: server + port: 8300 + targetPort: 8300 + - name: dns-tcp + protocol: "TCP" + port: 8600 + targetPort: dns-tcp + - name: dns-udp + protocol: "UDP" + port: 8600 + targetPort: dns-udp + selector: + app: {{ template "consul.name" . }} + release: "{{ .Release.Name }}" + component: server +{{- end }} diff --git a/kubernetes-vault/consul/templates/server-serviceaccount.yaml b/kubernetes-vault/consul/templates/server-serviceaccount.yaml new file mode 100644 index 0000000..a161797 --- /dev/null +++ b/kubernetes-vault/consul/templates/server-serviceaccount.yaml @@ -0,0 +1,23 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "consul.fullname" . }}-server + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: server + {{- if .Values.server.serviceAccount.annotations }} + annotations: + {{ tpl .Values.server.serviceAccount.annotations . | nindent 4 | trim }} + {{- end }} +{{- with .Values.global.imagePullSecrets }} +imagePullSecrets: +{{- range . }} + - name: {{ .name }} +{{- end }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/server-snapshot-agent-configmap.yaml b/kubernetes-vault/consul/templates/server-snapshot-agent-configmap.yaml new file mode 100644 index 0000000..da68d15 --- /dev/null +++ b/kubernetes-vault/consul/templates/server-snapshot-agent-configmap.yaml @@ -0,0 +1,24 @@ +{{- if .Values.server.snapshotAgent.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "consul.fullname" . }}-snapshot-agent-config + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: server +data: + snapshot-login.json: | + { + "snapshot_agent": { + "login": { + "auth_method": "{{ template "consul.fullname" . }}-k8s-component-auth-method", + "bearer_token_file": "/var/run/secrets/kubernetes.io/serviceaccount/token", + "meta": {"component": "snapshot-agent"} + } + } + } +{{- end }} diff --git a/kubernetes-vault/consul/templates/server-statefulset.yaml b/kubernetes-vault/consul/templates/server-statefulset.yaml new file mode 100644 index 0000000..f8cb9b4 --- /dev/null +++ b/kubernetes-vault/consul/templates/server-statefulset.yaml @@ -0,0 +1,757 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if and .Values.global.federation.enabled .Values.global.adminPartitions.enabled }}{{ fail "If global.federation.enabled is true, global.adminPartitions.enabled must be false because they are mutually exclusive" }}{{ end }} +{{- if and .Values.global.federation.enabled (not .Values.global.tls.enabled) }}{{ fail "If global.federation.enabled is true, global.tls.enabled must be true because federation is only supported with TLS enabled" }}{{ end }} +{{- if and .Values.global.federation.enabled (not .Values.meshGateway.enabled) }}{{ fail "If global.federation.enabled is true, meshGateway.enabled must be true because mesh gateways are required for federation" }}{{ end }} +{{- if and .Values.server.serverCert.secretName (not .Values.global.tls.caCert.secretName) }}{{ fail "If server.serverCert.secretName is provided, global.tls.caCert must also be provided" }}{{ end }} +{{- if .Values.server.disableFsGroupSecurityContext }}{{ fail "server.disableFsGroupSecurityContext has been removed. Please use global.openshift.enabled instead." }}{{ end }} +{{- if .Values.server.bootstrapExpect }}{{ if lt (int .Values.server.bootstrapExpect) (int .Values.server.replicas) }}{{ fail "server.bootstrapExpect cannot be less than server.replicas" }}{{ end }}{{ end }} +{{- if (and .Values.global.gossipEncryption.secretName (not .Values.global.gossipEncryption.secretKey)) }}{{fail "gossipEncryption.secretKey and secretName must both be specified." }}{{ end -}} +{{- if (and (not .Values.global.gossipEncryption.secretName) .Values.global.gossipEncryption.secretKey) }}{{fail "gossipEncryption.secretKey and secretName must both be specified." }}{{ end -}} +{{- if (and .Values.global.secretsBackend.vault.enabled (not .Values.global.secretsBackend.vault.consulServerRole)) }}{{ fail "global.secretsBackend.vault.consulServerRole must be provided if global.secretsBackend.vault.enabled=true." }}{{ end -}} +{{- if (and .Values.server.serverCert.secretName (not .Values.global.tls.caCert.secretName)) }}{{ fail "If server.serverCert.secretName is provided, global.tls.caCert.secretName must also be provided" }}{{ end }} +{{- if (and (and .Values.global.secretsBackend.vault.enabled .Values.global.tls.enabled) (not .Values.global.tls.caCert.secretName)) }}{{ fail "global.tls.caCert.secretName must be provided if global.tls.enabled=true and global.secretsBackend.vault.enabled=true." }}{{ end -}} +{{- if (and .Values.global.enterpriseLicense.secretName (not .Values.global.enterpriseLicense.secretKey)) }}{{fail "enterpriseLicense.secretKey and secretName must both be specified." }}{{ end -}} +{{- if (and (not .Values.global.enterpriseLicense.secretName) .Values.global.enterpriseLicense.secretKey) }}{{fail "enterpriseLicense.secretKey and secretName must both be specified." }}{{ end -}} +{{- if (and .Values.global.acls.bootstrapToken.secretName (not .Values.global.acls.bootstrapToken.secretKey)) }}{{fail "both global.acls.bootstrapToken.secretKey and global.acls.bootstrapToken.secretName must be set if one of them is provided." }}{{ end -}} +{{- if (and (not .Values.global.acls.bootstrapToken.secretName) .Values.global.acls.bootstrapToken.secretKey) }}{{fail "both global.acls.bootstrapToken.secretKey and global.acls.bootstrapToken.secretName must be set if one of them is provided." }}{{ end -}} +{{- if .Values.server.snapshotAgent.enabled -}} +{{- if or (and .Values.server.snapshotAgent.configSecret.secretName (not .Values.server.snapshotAgent.configSecret.secretKey)) (and (not .Values.server.snapshotAgent.configSecret.secretName) .Values.server.snapshotAgent.configSecret.secretKey) }}{{fail "server.snapshotAgent.configSecret.secretKey and server.snapshotAgent.configSecret.secretName must both be specified." }}{{ end -}} +{{- end -}} +{{ template "consul.validateRequiredCloudSecretsExist" . }} +{{ template "consul.validateCloudSecretKeys" . }} +{{ template "consul.validateMetricsConfig" . }} +{{ template "consul.validateDatadogConfiguration" . }} +{{ template "consul.validateExtraConfig" . }} +# StatefulSet to run the actual Consul server cluster. +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ template "consul.fullname" . }}-server + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: server + {{- if .Values.global.extraLabels }} + {{- toYaml .Values.global.extraLabels | nindent 4 }} + {{- end }} +spec: + serviceName: {{ template "consul.fullname" . }}-server + podManagementPolicy: Parallel + replicas: {{ .Values.server.replicas }} + {{- if (gt (int .Values.server.updatePartition) 0) }} + updateStrategy: + type: RollingUpdate + rollingUpdate: + partition: {{ .Values.server.updatePartition }} + {{- end }} + {{- if and (semverCompare ">= 1.23-0" .Capabilities.KubeVersion.Version) (.Values.server.persistentVolumeClaimRetentionPolicy) }} + persistentVolumeClaimRetentionPolicy: {{ toYaml .Values.server.persistentVolumeClaimRetentionPolicy | nindent 4 }} + {{- end }} + selector: + matchLabels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: server + hasDNS: "true" + template: + metadata: + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: server + hasDNS: "true" + {{- if .Values.global.metrics.datadog.enabled }} + "tags.datadoghq.com/version": {{ template "consul.versionInfo" . }} + "tags.datadoghq.com/env": {{ template "consul.name" . }} + "tags.datadoghq.com/service": "consul-server" + {{- end }} + {{- if .Values.server.extraLabels }} + {{- toYaml .Values.server.extraLabels | nindent 8 }} + {{- end }} + {{- if .Values.global.extraLabels }} + {{- toYaml .Values.global.extraLabels | nindent 8 }} + {{- end }} + annotations: + {{- if .Values.global.secretsBackend.vault.enabled }} + "vault.hashicorp.com/agent-inject": "true" + "vault.hashicorp.com/role": "{{ .Values.global.secretsBackend.vault.consulServerRole }}" + {{- if and .Values.global.secretsBackend.vault.ca.secretName .Values.global.secretsBackend.vault.ca.secretKey }} + "vault.hashicorp.com/agent-extra-secret": {{ .Values.global.secretsBackend.vault.ca.secretName }} + "vault.hashicorp.com/ca-cert": /vault/custom/{{ .Values.global.secretsBackend.vault.ca.secretKey }} + {{- end }} + {{- if .Values.global.gossipEncryption.secretName }} + {{- with .Values.global.gossipEncryption }} + "vault.hashicorp.com/agent-inject-secret-gossip.txt": "{{ .secretName }}" + "vault.hashicorp.com/agent-inject-template-gossip.txt": {{ template "consul.vaultSecretTemplate" . }} + {{- end }} + {{- end }} + {{- if .Values.server.serverCert.secretName }} + "vault.hashicorp.com/agent-inject-secret-servercert.crt": {{ .Values.server.serverCert.secretName }} + "vault.hashicorp.com/agent-inject-template-servercert.crt": {{ include "consul.serverTLSCertTemplate" . }} + "vault.hashicorp.com/agent-inject-secret-servercert.key": {{ .Values.server.serverCert.secretName }} + "vault.hashicorp.com/agent-inject-template-servercert.key": {{ include "consul.serverTLSKeyTemplate" . }} + "vault.hashicorp.com/agent-inject-secret-serverca.crt": {{ .Values.global.tls.caCert.secretName }} + "vault.hashicorp.com/agent-inject-template-serverca.crt": {{ include "consul.serverTLSCATemplate" . }} + {{- end }} + {{- if (and .Values.global.acls.replicationToken.secretName (not .Values.global.acls.createReplicationToken)) }} + "vault.hashicorp.com/agent-inject-secret-replication-token-config.hcl": "{{ .Values.global.acls.replicationToken.secretName }}" + "vault.hashicorp.com/agent-inject-template-replication-token-config.hcl": {{ template "consul.vaultReplicationTokenConfigTemplate" . }} + {{- end }} + {{- if (and .Values.global.acls.manageSystemACLs .Values.global.acls.bootstrapToken.secretName) }} + "vault.hashicorp.com/agent-inject-secret-bootstrap-token-config.hcl": "{{ .Values.global.acls.bootstrapToken.secretName }}" + "vault.hashicorp.com/agent-inject-template-bootstrap-token-config.hcl": {{ template "consul.vaultBootstrapTokenConfigTemplate" . }} + {{- end }} + {{- if .Values.global.secretsBackend.vault.agentAnnotations }} + {{ tpl .Values.global.secretsBackend.vault.agentAnnotations . | nindent 8 | trim }} + {{- end }} + {{- if (and (.Values.global.secretsBackend.vault.vaultNamespace) (not (hasKey (default "" .Values.global.secretsBackend.vault.agentAnnotations | fromYaml) "vault.hashicorp.com/namespace")))}} + "vault.hashicorp.com/namespace": "{{ .Values.global.secretsBackend.vault.vaultNamespace }}" + {{- end }} + {{- if .Values.global.enterpriseLicense.secretName }} + {{- with .Values.global.enterpriseLicense }} + "vault.hashicorp.com/agent-inject-secret-enterpriselicense.txt": "{{ .secretName }}" + "vault.hashicorp.com/agent-inject-template-enterpriselicense.txt": {{ template "consul.vaultSecretTemplate" . }} + {{- end }} + {{- end }} + {{- if .Values.server.snapshotAgent.configSecret.secretName }} + {{- with .Values.server.snapshotAgent.configSecret }} + "vault.hashicorp.com/agent-inject-secret-snapshot-agent-config.json": "{{ .secretName }}" + "vault.hashicorp.com/agent-inject-template-snapshot-agent-config.json": {{ template "consul.vaultSecretTemplate" . }} + {{- end }} + {{- end }} + {{- end }} + "consul.hashicorp.com/connect-inject": "false" + "consul.hashicorp.com/mesh-inject": "false" + "consul.hashicorp.com/config-checksum": {{ print (include (print $.Template.BasePath "/server-config-configmap.yaml") .) (include (print $.Template.BasePath "/server-tmp-extra-config-configmap.yaml") .) | sha256sum }} + {{- if .Values.server.annotations }} + {{- tpl .Values.server.annotations . | nindent 8 }} + {{- end }} + {{- if (and .Values.global.metrics.enabled .Values.global.metrics.enableAgentMetrics) }} + {{- if (or (not .Values.global.metrics.datadog.enabled) (and .Values.global.metrics.datadog.enabled (.Values.global.metrics.datadog.dogstatsd.enabled))) }} + "prometheus.io/scrape": "true" + {{- if not (hasKey (default "" .Values.server.annotations | fromYaml) "prometheus.io/path")}} + "prometheus.io/path": "/v1/agent/metrics" + {{- end }} + {{- if .Values.global.tls.enabled }} + "prometheus.io/port": "8501" + "prometheus.io/scheme": "https" + {{- else }} + "prometheus.io/port": "8500" + "prometheus.io/scheme": "http" + {{- end }} + {{- end }} + {{- if .Values.global.metrics.datadog.enabled }} + "ad.datadoghq.com/tolerate-unready": "true" + "ad.datadoghq.com/consul.logs": {{ .Values.global.metrics.datadog.dogstatsd.dogstatsdTags | toJson | replace "[" "[{" | replace "]" "}]" | replace ":" "\": \"" | join "\",\"" | squote }} + {{- if .Values.global.metrics.datadog.openMetricsPrometheus.enabled }} + "ad.datadoghq.com/consul.checks": | + { + "openmetrics": { + "init_config": {}, + "instances": [ + { + {{- if .Values.global.tls.enabled }} + "openmetrics_endpoint": "https://{{ template "consul.fullname" . }}-server.{{ .Release.Namespace }}.svc:8501/v1/agent/metrics?format=prometheus", + "tls_cert": "/etc/datadog-agent/conf.d/consul.d/certs/tls.crt", + "tls_private_key": "/etc/datadog-agent/conf.d/consul.d/certs/tls.key", + "tls_ca_cert": "/etc/datadog-agent/conf.d/consul.d/ca/tls.crt", + {{- else }} + "openmetrics_endpoint": "http://{{ template "consul.fullname" . }}-server.{{ .Release.Namespace }}.svc:8500/v1/agent/metrics?format=prometheus", + {{- end }} + {{- if ( .Values.global.acls.manageSystemACLs) }} + "headers": { + "X-Consul-Token": "ENC[k8s_secret@{{ .Release.Namespace }}/{{ .Release.Namespace }}-datadog-agent-metrics-acl-token/token]" + }, + {{- end }} + "namespace": "{{ .Release.Namespace }}", + "metrics": [ ".*" ] + } + ] + } + } + {{- else if (not .Values.global.metrics.datadog.dogstatsd.enabled) }} + "ad.datadoghq.com/consul.checks": | + { + "consul": { + "init_config": {}, + "instances": [ + { + {{- if .Values.global.tls.enabled }} + "url": "https://{{ template "consul.fullname" . }}-server.{{ .Release.Namespace }}.svc:8501", + "tls_cert": "/etc/datadog-agent/conf.d/consul.d/certs/tls.crt", + "tls_private_key": "/etc/datadog-agent/conf.d/consul.d/certs/tls.key", + "tls_ca_cert": "/etc/datadog-agent/conf.d/consul.d/ca/tls.crt", + {{- else }} + "url": "http://{{ template "consul.fullname" . }}-server.{{ .Release.Namespace }}.svc:8500", + {{- end }} + "use_prometheus_endpoint": true, + {{- if ( .Values.global.acls.manageSystemACLs) }} + "acl_token": "ENC[k8s_secret@{{ .Release.Namespace }}/{{ .Release.Namespace }}-datadog-agent-metrics-acl-token/token]", + {{- end }} + "new_leader_checks": true, + "network_latency_checks": true, + "catalog_checks": true, + "auth_type": "basic" + } + ] + } + } + {{- else }} + "ad.datadoghq.com/consul.metrics_exclude": "true" + {{- end }} + {{- end }} + {{- end }} + spec: + {{- if .Values.server.affinity }} + affinity: + {{ tpl .Values.server.affinity . | nindent 8 | trim }} + {{- end }} + {{- if .Values.server.tolerations }} + tolerations: + {{ tpl .Values.server.tolerations . | nindent 8 | trim }} + {{- end }} + {{- if .Values.server.topologySpreadConstraints }} + topologySpreadConstraints: + {{ tpl .Values.server.topologySpreadConstraints . | nindent 8 | trim }} + {{- end }} + terminationGracePeriodSeconds: 30 + serviceAccountName: {{ template "consul.fullname" . }}-server + {{- if not .Values.global.openshift.enabled }} + securityContext: + {{- toYaml .Values.server.securityContext | nindent 8 }} + {{- end }} + volumes: + - name: tmp + emptyDir: {} + - name: config + configMap: + name: {{ template "consul.fullname" . }}-server-config + - name: extra-config + emptyDir: {} + - name: tmp-extra-config + configMap: + name: {{ template "consul.fullname" . }}-server-tmp-extra-config + {{- if (and .Values.global.tls.enabled (not .Values.global.secretsBackend.vault.enabled)) }} + - name: consul-ca-cert + secret: + {{- if .Values.global.tls.caCert.secretName }} + secretName: {{ .Values.global.tls.caCert.secretName }} + {{- else }} + secretName: {{ template "consul.fullname" . }}-ca-cert + {{- end }} + items: + - key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }} + path: tls.crt + - name: consul-server-cert + secret: + {{- if .Values.server.serverCert.secretName }} + secretName: {{ .Values.server.serverCert.secretName }} + {{- else }} + secretName: {{ template "consul.fullname" . }}-server-cert + {{- end }} + {{- end }} + {{- if (and .Values.global.enterpriseLicense.secretName .Values.global.enterpriseLicense.enableLicenseAutoload (not .Values.global.secretsBackend.vault.enabled)) }} + - name: consul-license + secret: + secretName: {{ .Values.global.enterpriseLicense.secretName }} + {{- end }} + {{- if and .Values.global.secretsBackend.vault.ca.secretName .Values.global.secretsBackend.vault.ca.secretKey }} + - name: vault-ca + secret: + secretName: {{ .Values.global.secretsBackend.vault.ca.secretName }} + items: + - key: {{ .Values.global.secretsBackend.vault.ca.secretKey }} + path: tls.crt + {{- end }} + {{- if .Values.server.snapshotAgent.enabled }} + {{- if .Values.global.acls.manageSystemACLs }} + - name: snapshot-agent-config + configMap: + name: {{ template "consul.fullname" . }}-snapshot-agent-config + {{- end }} + {{- if (and .Values.server.snapshotAgent.configSecret.secretName .Values.server.snapshotAgent.configSecret.secretKey (not .Values.global.secretsBackend.vault.enabled)) }} + - name: snapshot-agent-user-config + secret: + secretName: {{ .Values.server.snapshotAgent.configSecret.secretName }} + items: + - key: {{ .Values.server.snapshotAgent.configSecret.secretKey }} + path: snapshot-config.json + {{- end }} + {{- if .Values.server.snapshotAgent.caCert }} + - name: extra-ssl-certs + emptyDir: + medium: "Memory" + {{- end }} + {{- end }} + {{- if .Values.global.trustedCAs }} + - name: trusted-cas + emptyDir: + medium: "Memory" + {{- end }} + {{- if and .Values.global.metrics.datadog.enabled .Values.global.metrics.datadog.dogstatsd.enabled (eq .Values.global.metrics.datadog.dogstatsd.socketTransportType "UDS" ) }} + - name: dsdsocket + hostPath: + path: {{ dir .Values.global.metrics.datadog.dogstatsd.dogstatsdAddr | trimAll "\"" }} + type: DirectoryOrCreate + {{- end }} + {{- range .Values.server.extraVolumes }} + - name: userconfig-{{ .name }} + {{ .type }}: + {{- if (eq .type "configMap") }} + name: {{ .name }} + {{- else if (eq .type "secret") }} + secretName: {{ .name }} + {{- end }} + {{- with .items }} + items: + {{- range . }} + - key: {{.key}} + path: {{.path}} + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.server.priorityClassName }} + priorityClassName: {{ .Values.server.priorityClassName | quote }} + {{- end }} + initContainers: + - name: locality-init + image: {{ .Values.global.imageK8S }} + {{ template "consul.imagePullPolicy" . }} + env: + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + command: + - "/bin/sh" + - "-ec" + - | + exec consul-k8s-control-plane fetch-server-region -node-name "$NODE_NAME" -output-file /consul/extra-config/locality.json + volumeMounts: + - name: extra-config + mountPath: /consul/extra-config + {{- include "consul.restrictedSecurityContext" . | nindent 8 }} + containers: + - name: consul + image: "{{ default .Values.global.image .Values.server.image | trimPrefix "\"" | trimSuffix "\"" }}" + {{ template "consul.imagePullPolicy" . }} + imagePullPolicy: {{ .Values.global.imagePullPolicy }} + env: + - name: ADVERTISE_IP + valueFrom: + fieldRef: + {{- if .Values.server.exposeGossipAndRPCPorts }} + {{- /* Server gossip and RPC ports will be exposed as a hostPort + on the hostIP, so they need to advertise their host ip + instead of their pod ip. This is to support external client + agents. */}} + fieldPath: status.hostIP + {{- else }} + fieldPath: status.podIP + {{- end }} + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: CONSUL_DISABLE_PERM_MGMT + value: "true" + {{- if (or .Values.global.gossipEncryption.autoGenerate (and .Values.global.gossipEncryption.secretName .Values.global.gossipEncryption.secretKey)) }} + {{- if not .Values.global.secretsBackend.vault.enabled }} + - name: GOSSIP_KEY + valueFrom: + secretKeyRef: + {{- if .Values.global.gossipEncryption.autoGenerate }} + name: {{ template "consul.fullname" . }}-gossip-encryption-key + key: key + {{- else if (and .Values.global.gossipEncryption.secretName .Values.global.gossipEncryption.secretKey) }} + name: {{ .Values.global.gossipEncryption.secretName }} + key: {{ .Values.global.gossipEncryption.secretKey }} + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.global.tls.enabled }} + - name: CONSUL_HTTP_ADDR + value: https://localhost:8501 + - name: CONSUL_CACERT + {{- if .Values.global.secretsBackend.vault.enabled }} + value: /vault/secrets/serverca.crt + {{- else }} + value: /consul/tls/ca/tls.crt + {{- end }} + {{- end }} + {{- if (and .Values.global.enterpriseLicense.secretName .Values.global.enterpriseLicense.enableLicenseAutoload) }} + - name: CONSUL_LICENSE_PATH + {{- if .Values.global.secretsBackend.vault.enabled }} + value: /vault/secrets/enterpriselicense.txt + {{- else }} + value: /consul/license/{{ .Values.global.enterpriseLicense.secretKey }} + {{- end }} + {{- end }} + {{- if and (not .Values.global.secretsBackend.vault.enabled) .Values.global.acls.bootstrapToken.secretName }} + - name: ACL_BOOTSTRAP_TOKEN + valueFrom: + secretKeyRef: + name: {{ .Values.global.acls.bootstrapToken.secretName | quote }} + key: {{ .Values.global.acls.bootstrapToken.secretKey | quote }} + {{- end }} + {{- if (and .Values.global.acls.replicationToken.secretName .Values.global.acls.replicationToken.secretKey (not .Values.global.secretsBackend.vault.enabled)) }} + - name: ACL_REPLICATION_TOKEN + valueFrom: + secretKeyRef: + name: {{ .Values.global.acls.replicationToken.secretName | quote }} + key: {{ .Values.global.acls.replicationToken.secretKey | quote }} + {{- end }} + {{- if .Values.global.cloud.enabled}} + # These are mounted as secrets so that the consul server agent can use them. + # - the hcp-go-sdk in consul agent will already look for HCP_CLIENT_ID, HCP_CLIENT_SECRET, HCP_AUTH_URL, + # HCP_SCADA_ADDRESS, and HCP_API_HOST. so nothing more needs to be done. + # - HCP_RESOURCE_ID is created for use in the + # `-hcl="cloud { resource_id = \"${HCP_RESOURCE_ID}\" }"` logic in the command below. + {{- if .Values.global.cloud.clientId.secretName }} + - name: HCP_CLIENT_ID + valueFrom: + secretKeyRef: + name: {{ .Values.global.cloud.clientId.secretName }} + key: {{ .Values.global.cloud.clientId.secretKey }} + {{- end }} + {{- if .Values.global.cloud.clientSecret.secretName }} + - name: HCP_CLIENT_SECRET + valueFrom: + secretKeyRef: + name: {{ .Values.global.cloud.clientSecret.secretName }} + key: {{ .Values.global.cloud.clientSecret.secretKey }} + {{- end}} + {{- if .Values.global.cloud.resourceId.secretName }} + - name: HCP_RESOURCE_ID + valueFrom: + secretKeyRef: + name: {{ .Values.global.cloud.resourceId.secretName }} + key: {{ .Values.global.cloud.resourceId.secretKey }} + {{- end }} + {{- if .Values.global.cloud.authUrl.secretName }} + - name: HCP_AUTH_URL + valueFrom: + secretKeyRef: + name: {{ .Values.global.cloud.authUrl.secretName }} + key: {{ .Values.global.cloud.authUrl.secretKey }} + {{- end}} + {{- if .Values.global.cloud.apiHost.secretName }} + - name: HCP_API_HOST + valueFrom: + secretKeyRef: + name: {{ .Values.global.cloud.apiHost.secretName }} + key: {{ .Values.global.cloud.apiHost.secretKey }} + {{- end}} + {{- if .Values.global.cloud.scadaAddress.secretName }} + - name: HCP_SCADA_ADDRESS + valueFrom: + secretKeyRef: + name: {{ .Values.global.cloud.scadaAddress.secretName }} + key: {{ .Values.global.cloud.scadaAddress.secretKey }} + {{- end}} + {{- end }} + {{- if .Values.global.trustedCAs }} + - name: SSL_CERT_DIR + value: "/etc/ssl/certs:/trusted-cas" + {{- end }} + {{- include "consul.extraEnvironmentVars" .Values.server | nindent 12 }} + command: + - "/bin/sh" + - "-ec" + - | + {{- if .Values.global.trustedCAs }} + {{- range $i, $cert := .Values.global.trustedCAs }} + cat < /trusted-cas/custom-ca-{{$i}}.pem + {{- $cert | nindent 14 }} + EOF + {{- end }} + {{- end }} + + {{- if and .Values.global.secretsBackend.vault.enabled .Values.global.gossipEncryption.secretName }} + GOSSIP_KEY=`cat /vault/secrets/gossip.txt` + {{- end }} + + {{ template "consul.extraconfig" }} + + exec /usr/local/bin/docker-entrypoint.sh consul agent \ + -advertise="${ADVERTISE_IP}" \ + -config-dir=/consul/config \ + {{- if (or .Values.global.gossipEncryption.autoGenerate (and .Values.global.gossipEncryption.secretName .Values.global.gossipEncryption.secretKey)) }} + -encrypt="${GOSSIP_KEY}" \ + {{- end }} + {{- if (and .Values.global.acls.replicationToken.secretName .Values.global.acls.replicationToken.secretKey) }} + {{- if (and .Values.global.secretsBackend.vault.enabled (not .Values.global.acls.createReplicationToken)) }} + -config-file=/vault/secrets/replication-token-config.hcl \ + {{- else }} + -hcl="acl { tokens { agent = \"${ACL_REPLICATION_TOKEN}\", replication = \"${ACL_REPLICATION_TOKEN}\" } }" \ + {{- end }} + {{- end }} + {{- if and .Values.global.secretsBackend.vault.enabled .Values.global.acls.bootstrapToken.secretName }} + -config-file=/vault/secrets/bootstrap-token-config.hcl \ + {{- else if (and (not .Values.global.secretsBackend.vault.enabled) .Values.global.acls.bootstrapToken.secretName) }} + -hcl="acl { tokens { initial_management = \"${ACL_BOOTSTRAP_TOKEN}\" } }" \ + {{- end }} + {{- /* Always include the extraVolumes at the end so that users can + override other Consul settings. The last -config-dir takes + precedence. */}} + {{- range .Values.server.extraVolumes }} + {{- if .load }} + -config-dir=/consul/userconfig/{{ .name }} \ + {{- end }} + {{- end }} + -config-dir=/consul/extra-config \ + {{- if and .Values.global.cloud.enabled .Values.global.cloud.resourceId.secretName }} + -hcl="cloud { resource_id = \"${HCP_RESOURCE_ID}\" }" + {{- end }} + + {{- if .Values.global.experiments }} + {{- $commaSeparatedValues := "" }} + {{- range $index, $value := .Values.global.experiments }} + {{- if ne $index 0 }} + {{- $commaSeparatedValues = printf "%s,\\\"%s\\\"" $commaSeparatedValues $value }} + {{- else }} + {{- $commaSeparatedValues = printf "\\\"%s\\\"" $value }} + {{- end }} + {{- end }} + -hcl="experiments=[{{ $commaSeparatedValues }}]" + {{- end }} + volumeMounts: + - name: data-{{ .Release.Namespace | trunc 58 | trimSuffix "-" }} + mountPath: /consul/data + - name: config + mountPath: /consul/config + - name: extra-config + mountPath: /consul/extra-config + - name: tmp-extra-config + mountPath: /consul/tmp/extra-config + {{- if (and .Values.global.tls.enabled (not .Values.global.secretsBackend.vault.enabled)) }} + - name: consul-ca-cert + mountPath: /consul/tls/ca/ + readOnly: true + - name: consul-server-cert + mountPath: /consul/tls/server + readOnly: true + {{- end }} + {{- if (and .Values.global.enterpriseLicense.secretName .Values.global.enterpriseLicense.enableLicenseAutoload (not .Values.global.secretsBackend.vault.enabled)) }} + - name: consul-license + mountPath: /consul/license + readOnly: true + {{- end }} + {{- if and .Values.global.metrics.datadog.enabled .Values.global.metrics.datadog.dogstatsd.enabled (eq .Values.global.metrics.datadog.dogstatsd.socketTransportType "UDS" ) }} + - name: dsdsocket + mountPath: {{ dir .Values.global.metrics.datadog.dogstatsd.dogstatsdAddr | trimAll "\"" }} + readOnly: true + {{- end }} + {{- range .Values.server.extraVolumes }} + - name: userconfig-{{ .name }} + readOnly: true + mountPath: /consul/userconfig/{{ .name }} + {{- end }} + {{- if and .Values.global.secretsBackend.vault.ca.secretName .Values.global.secretsBackend.vault.ca.secretKey }} + - name: vault-ca + mountPath: /consul/vault-ca/ + readOnly: true + {{- end }} + {{- if .Values.global.trustedCAs }} + - name: trusted-cas + mountPath: /trusted-cas + readOnly: false + {{- end }} + - name: tmp + mountPath: /tmp + readOnly: false + ports: + {{- if (or (not .Values.global.tls.enabled) (not .Values.global.tls.httpsOnly)) }} + - name: http + containerPort: 8500 + {{- end }} + {{- if .Values.global.tls.enabled }} + - name: https + containerPort: 8501 + {{- end }} + - name: grpc + containerPort: 8502 + {{- if .Values.server.exposeGossipAndRPCPorts }} + hostPort: 8502 + {{- end }} + protocol: "TCP" + - name: serflan-tcp + containerPort: {{ .Values.server.ports.serflan.port }} + {{- if .Values.server.exposeGossipAndRPCPorts }} + hostPort: {{ .Values.server.ports.serflan.port }} + {{- end }} + protocol: "TCP" + - name: serflan-udp + containerPort: {{ .Values.server.ports.serflan.port }} + {{- if .Values.server.exposeGossipAndRPCPorts }} + hostPort: {{ .Values.server.ports.serflan.port }} + {{- end }} + protocol: "UDP" + - name: serfwan-tcp + containerPort: 8302 + {{- if .Values.server.exposeGossipAndRPCPorts }} + hostPort: 8302 + {{- end }} + protocol: "TCP" + - name: serfwan-udp + containerPort: 8302 + {{- if .Values.server.exposeGossipAndRPCPorts }} + hostPort: 8302 + {{- end }} + protocol: "UDP" + - name: server + containerPort: 8300 + {{- if .Values.server.exposeGossipAndRPCPorts }} + hostPort: 8300 + {{- end }} + - name: dns-tcp + containerPort: 8600 + protocol: "TCP" + - name: dns-udp + containerPort: 8600 + protocol: "UDP" + readinessProbe: + # NOTE(mitchellh): when our HTTP status endpoints support the + # proper status codes, we should switch to that. This is temporary. + exec: + command: + - "/bin/sh" + - "-ec" + - | + {{- if .Values.global.tls.enabled }} + curl -k \ + https://127.0.0.1:8501/v1/status/leader \ + {{- else }} + curl http://127.0.0.1:8500/v1/status/leader \ + {{- end }} + 2>/dev/null | grep -E '".+"' + failureThreshold: 2 + initialDelaySeconds: 5 + periodSeconds: 3 + successThreshold: 1 + timeoutSeconds: 5 + {{- if .Values.server.resources }} + resources: + {{- if eq (typeOf .Values.server.resources) "string" }} + {{ tpl .Values.server.resources . | nindent 12 | trim }} + {{- else }} + {{- toYaml .Values.server.resources | nindent 12 }} + {{- end }} + {{- end }} + {{- if .Values.server.containerSecurityContext.server }} + securityContext: + {{- toYaml .Values.server.containerSecurityContext.server | nindent 12 }} + {{- else }} + {{- include "consul.restrictedSecurityContext" . | nindent 10 }} + {{- end }} + {{- if .Values.server.extraContainers }} + {{ toYaml .Values.server.extraContainers | nindent 8 }} + {{- end }} + {{- if .Values.server.snapshotAgent.enabled }} + - name: consul-snapshot-agent + image: "{{ default .Values.global.image .Values.server.image }}" + {{ template "consul.imagePullPolicy" . }} + env: + {{- if .Values.server.snapshotAgent.caCert }} + - name: SSL_CERT_DIR + value: "/etc/ssl/certs:/extra-ssl-certs" + {{- end }} + {{- if .Values.global.tls.enabled }} + - name: CONSUL_HTTP_ADDR + value: https://127.0.0.1:8501 + - name: CONSUL_CACERT + {{- if .Values.global.secretsBackend.vault.enabled }} + value: /vault/secrets/serverca.crt + {{- else }} + value: /consul/tls/ca/tls.crt + {{- end }} + {{- else }} + - name: CONSUL_HTTP_ADDR + value: http://127.0.0.1:8500 + {{- end }} + {{- if (and .Values.global.enterpriseLicense.secretName .Values.global.enterpriseLicense.secretKey .Values.global.enterpriseLicense.enableLicenseAutoload (not .Values.global.acls.manageSystemACLs)) }} + - name: CONSUL_LICENSE_PATH + {{- if .Values.global.secretsBackend.vault.enabled }} + value: /vault/secrets/enterpriselicense.txt + {{- else }} + value: /consul/license/{{ .Values.global.enterpriseLicense.secretKey }} + {{- end }} + {{- end }} + command: + - "/bin/sh" + - "-ec" + - | + {{- if .Values.server.snapshotAgent.caCert }} + cat < /extra-ssl-certs/custom-ca.pem + {{- .Values.server.snapshotAgent.caCert | nindent 14 }} + EOF + {{- end }} + exec /bin/consul snapshot agent \ + -interval={{ .Values.server.snapshotAgent.interval }} \ + {{- if .Values.global.acls.manageSystemACLs }} + -config-file=/consul/config/snapshot-login.json \ + {{- end }} + {{- if (and .Values.server.snapshotAgent.configSecret.secretName .Values.server.snapshotAgent.configSecret.secretKey) }} + {{- if .Values.global.secretsBackend.vault.enabled }} + -config-file=/vault/secrets/snapshot-agent-config.json \ + {{- else }} + -config-dir=/consul/user-config \ + {{- end }} + {{- end }} + volumeMounts: + {{- if .Values.global.acls.manageSystemACLs }} + - name: snapshot-agent-config + mountPath: /consul/config + readOnly: true + {{- end }} + {{- if .Values.server.snapshotAgent.caCert }} + - name: extra-ssl-certs + mountPath: /extra-ssl-certs + readOnly: false + {{- end }} + {{- if (and .Values.server.snapshotAgent.configSecret.secretName .Values.server.snapshotAgent.configSecret.secretKey (not .Values.global.secretsBackend.vault.enabled)) }} + - name: snapshot-agent-user-config + mountPath: /consul/user-config + readOnly: true + {{- end }} + {{- if (and .Values.global.enterpriseLicense.secretName .Values.global.enterpriseLicense.secretKey .Values.global.enterpriseLicense.enableLicenseAutoload (not .Values.global.secretsBackend.vault.enabled) (not .Values.global.acls.manageSystemACLs))}} + - name: consul-license + mountPath: /consul/license + readOnly: true + {{- end }} + {{- if and .Values.global.tls.enabled (not .Values.global.secretsBackend.vault.enabled) }} + - name: consul-ca-cert + mountPath: /consul/tls/ca + readOnly: true + {{- end }} + {{- with .Values.server.snapshotAgent.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- end }} + {{- if .Values.server.nodeSelector }} + nodeSelector: + {{ tpl .Values.server.nodeSelector . | indent 8 | trim }} + {{- end }} + volumeClaimTemplates: + - metadata: + name: data-{{ .Release.Namespace | trunc 58 | trimSuffix "-" }} + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.server.storage }} + {{- if .Values.server.storageClass }} + storageClassName: {{ .Values.server.storageClass }} + {{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/server-tmp-extra-config-configmap.yaml b/kubernetes-vault/consul/templates/server-tmp-extra-config-configmap.yaml new file mode 100644 index 0000000..a42d6d0 --- /dev/null +++ b/kubernetes-vault/consul/templates/server-tmp-extra-config-configmap.yaml @@ -0,0 +1,21 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +# ConfigMap that is used as a temporary landing spot so that the container command +# in the server-stateful set where it needs to be transformed. ConfigMaps create +# read only volumes so it needs to be copied and transformed to the extra-config +# emptyDir volume where all final extra cofngi lives for use in consul. (locality-init +# also writes to extra-config volume.) +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "consul.fullname" . }}-server-tmp-extra-config + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: server +data: + extra-from-values.json: |- +{{ tpl .Values.server.extraConfig . | trimAll "\"" | indent 4 }} +{{- end }} \ No newline at end of file diff --git a/kubernetes-vault/consul/templates/sync-catalog-clusterrole.yaml b/kubernetes-vault/consul/templates/sync-catalog-clusterrole.yaml new file mode 100644 index 0000000..89ea9f3 --- /dev/null +++ b/kubernetes-vault/consul/templates/sync-catalog-clusterrole.yaml @@ -0,0 +1,60 @@ +{{- $syncEnabled := (or (and (ne (.Values.syncCatalog.enabled | toString) "-") .Values.syncCatalog.enabled) (and (eq (.Values.syncCatalog.enabled | toString) "-") .Values.global.enabled)) }} +{{- if $syncEnabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "consul.fullname" . }}-sync-catalog + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: sync-catalog +rules: +- apiGroups: [ "" ] + resources: + - services + verbs: + - get + - list + - watch +{{- if .Values.syncCatalog.toK8S }} + - update + - patch + - delete + - create +{{- end }} +- apiGroups: ["discovery.k8s.io"] + resources: + - endpointslices + verbs: + - get + - list + - watch +{{- if .Values.syncCatalog.toK8S }} + - update + - patch + - delete + - create +{{- end }} +- apiGroups: [ "" ] + resources: + - nodes + verbs: + - get +{{- if .Values.global.enablePodSecurityPolicies }} +- apiGroups: [ "policy" ] + resources: [ "podsecuritypolicies" ] + verbs: + - use + resourceNames: + - {{ template "consul.fullname" . }}-sync-catalog +{{- end }} +- apiGroups: [ "networking.k8s.io" ] + resources: + - ingresses + verbs: + - get + - list + - watch +{{- end }} diff --git a/kubernetes-vault/consul/templates/sync-catalog-clusterrolebinding.yaml b/kubernetes-vault/consul/templates/sync-catalog-clusterrolebinding.yaml new file mode 100644 index 0000000..818823c --- /dev/null +++ b/kubernetes-vault/consul/templates/sync-catalog-clusterrolebinding.yaml @@ -0,0 +1,21 @@ +{{- $syncEnabled := (or (and (ne (.Values.syncCatalog.enabled | toString) "-") .Values.syncCatalog.enabled) (and (eq (.Values.syncCatalog.enabled | toString) "-") .Values.global.enabled)) }} +{{- if $syncEnabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "consul.fullname" . }}-sync-catalog + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: sync-catalog +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "consul.fullname" . }}-sync-catalog +subjects: + - kind: ServiceAccount + name: {{ template "consul.fullname" . }}-sync-catalog + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/sync-catalog-deployment.yaml b/kubernetes-vault/consul/templates/sync-catalog-deployment.yaml new file mode 100644 index 0000000..963e6b2 --- /dev/null +++ b/kubernetes-vault/consul/templates/sync-catalog-deployment.yaml @@ -0,0 +1,238 @@ +{{- if (or (and (ne (.Values.syncCatalog.enabled | toString) "-") .Values.syncCatalog.enabled) (and (eq (.Values.syncCatalog.enabled | toString) "-") .Values.global.enabled)) }} +{{- template "consul.reservedNamesFailer" (list .Values.syncCatalog.consulNamespaces.consulDestinationNamespace "syncCatalog.consulNamespaces.consulDestinationNamespace") }} +{{ template "consul.validateRequiredCloudSecretsExist" . }} +{{ template "consul.validateCloudSecretKeys" . }} +# The deployment for running the sync-catalog pod +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "consul.fullname" . }}-sync-catalog + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: sync-catalog + {{- if .Values.global.extraLabels }} + {{- toYaml .Values.global.extraLabels | nindent 4 }} + {{- end }} +spec: + replicas: 1 + selector: + matchLabels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: sync-catalog + template: + metadata: + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: sync-catalog + {{- if .Values.syncCatalog.extraLabels }} + {{- toYaml .Values.syncCatalog.extraLabels | nindent 8 }} + {{- end }} + {{- if .Values.global.extraLabels }} + {{- toYaml .Values.global.extraLabels | nindent 8 }} + {{- end }} + annotations: + "consul.hashicorp.com/connect-inject": "false" + "consul.hashicorp.com/mesh-inject": "false" + {{- if .Values.syncCatalog.annotations }} + {{- tpl .Values.syncCatalog.annotations . | nindent 8 }} + {{- end }} + {{- if (and .Values.global.secretsBackend.vault.enabled .Values.global.tls.enabled) }} + "vault.hashicorp.com/agent-init-first": "true" + "vault.hashicorp.com/agent-inject": "true" + "vault.hashicorp.com/role": {{ .Values.global.secretsBackend.vault.consulCARole }} + "vault.hashicorp.com/agent-inject-secret-serverca.crt": {{ .Values.global.tls.caCert.secretName }} + "vault.hashicorp.com/agent-inject-template-serverca.crt": {{ template "consul.serverTLSCATemplate" . }} + {{- if and .Values.global.secretsBackend.vault.ca.secretName .Values.global.secretsBackend.vault.ca.secretKey }} + "vault.hashicorp.com/agent-extra-secret": "{{ .Values.global.secretsBackend.vault.ca.secretName }}" + "vault.hashicorp.com/ca-cert": "/vault/custom/{{ .Values.global.secretsBackend.vault.ca.secretKey }}" + {{- end }} + {{- if .Values.global.secretsBackend.vault.agentAnnotations }} + {{ tpl .Values.global.secretsBackend.vault.agentAnnotations . | nindent 8 | trim }} + {{- end }} + {{- if (and (.Values.global.secretsBackend.vault.vaultNamespace) (not (hasKey (default "" .Values.global.secretsBackend.vault.agentAnnotations | fromYaml) "vault.hashicorp.com/namespace")))}} + "vault.hashicorp.com/namespace": "{{ .Values.global.secretsBackend.vault.vaultNamespace }}" + {{- end }} + {{- end }} + spec: + serviceAccountName: {{ template "consul.fullname" . }}-sync-catalog + volumes: + {{- if .Values.global.tls.enabled }} + {{- if not (or (and .Values.externalServers.enabled .Values.externalServers.useSystemRoots) .Values.global.secretsBackend.vault.enabled) }} + - name: consul-ca-cert + secret: + {{- if .Values.global.tls.caCert.secretName }} + secretName: {{ .Values.global.tls.caCert.secretName }} + {{- else }} + secretName: {{ template "consul.fullname" . }}-ca-cert + {{- end }} + items: + - key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }} + path: tls.crt + {{- end }} + {{- end }} + containers: + - name: sync-catalog + image: "{{ default .Values.global.imageK8S .Values.syncCatalog.image }}" + {{ template "consul.imagePullPolicy" . }} + {{- include "consul.restrictedSecurityContext" . | nindent 8 }} + env: + {{- include "consul.consulK8sConsulServerEnvVars" . | nindent 8 }} + {{- if .Values.global.acls.manageSystemACLs }} + - name: CONSUL_LOGIN_AUTH_METHOD + {{- if and .Values.global.federation.enabled .Values.global.federation.primaryDatacenter .Values.global.enableConsulNamespaces }} + value: {{ template "consul.fullname" . }}-k8s-component-auth-method-{{ .Values.global.datacenter }} + {{- else }} + value: {{ template "consul.fullname" . }}-k8s-component-auth-method + {{- end }} + - name: CONSUL_LOGIN_DATACENTER + {{- if and .Values.global.federation.enabled .Values.global.federation.primaryDatacenter .Values.global.enableConsulNamespaces }} + value: {{ .Values.global.federation.primaryDatacenter }} + {{- else }} + value: {{ .Values.global.datacenter }} + {{- end }} + - name: CONSUL_LOGIN_META + value: "component=sync-catalog,pod=$(NAMESPACE)/$(POD_NAME)" + {{- end }} + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{- if (and .Values.syncCatalog.aclSyncToken.secretName .Values.syncCatalog.aclSyncToken.secretKey) }} + - name: CONSUL_ACL_TOKEN + valueFrom: + secretKeyRef: + name: {{ .Values.syncCatalog.aclSyncToken.secretName }} + key: {{ .Values.syncCatalog.aclSyncToken.secretKey }} + {{- end }} + volumeMounts: + {{- if .Values.global.tls.enabled }} + {{- if not (or (and .Values.externalServers.enabled .Values.externalServers.useSystemRoots) .Values.global.secretsBackend.vault.enabled) }} + - name: consul-ca-cert + mountPath: /consul/tls/ca + readOnly: true + {{- end }} + {{- end }} + command: + - "/bin/sh" + - "-ec" + - | + exec consul-k8s-control-plane sync-catalog \ + -log-level={{ default .Values.global.logLevel .Values.syncCatalog.logLevel }} \ + -log-json={{ .Values.global.logJSON }} \ + -k8s-default-sync={{ .Values.syncCatalog.default }} \ + {{- if (not .Values.syncCatalog.toConsul) }} + -to-consul=false \ + {{- end }} + {{- if (not .Values.syncCatalog.toK8S) }} + -to-k8s=false \ + {{- end }} + -consul-domain={{ .Values.global.domain }} \ + {{- if .Values.syncCatalog.k8sPrefix }} + -k8s-service-prefix="{{ .Values.syncCatalog.k8sPrefix}}" \ + {{- end }} + {{- if .Values.syncCatalog.k8sSourceNamespace }} + -k8s-source-namespace="{{ .Values.syncCatalog.k8sSourceNamespace}}" \ + {{- end }} + {{- range $value := .Values.syncCatalog.k8sAllowNamespaces }} + -allow-k8s-namespace="{{ $value }}" \ + {{- end }} + {{- range $value := .Values.syncCatalog.k8sDenyNamespaces }} + -deny-k8s-namespace="{{ $value }}" \ + {{- end }} + -k8s-write-namespace=${NAMESPACE} \ + {{- if (not .Values.syncCatalog.syncClusterIPServices) }} + -sync-clusterip-services=false \ + {{- end }} + {{- if .Values.syncCatalog.nodePortSyncType }} + -node-port-sync-type={{ .Values.syncCatalog.nodePortSyncType }} \ + {{- end }} + {{- if .Values.syncCatalog.consulWriteInterval }} + -consul-write-interval={{ .Values.syncCatalog.consulWriteInterval }} \ + {{- end }} + {{- if .Values.syncCatalog.k8sTag }} + -consul-k8s-tag={{ .Values.syncCatalog.k8sTag }} \ + {{- end }} + {{- if .Values.syncCatalog.consulNodeName }} + -consul-node-name={{ .Values.syncCatalog.consulNodeName }} \ + {{- end }} + {{- if .Values.global.adminPartitions.enabled }} + -partition={{ .Values.global.adminPartitions.name }} \ + {{- end }} + {{- if .Values.syncCatalog.consulPrefix}} + -consul-service-prefix="{{ .Values.syncCatalog.consulPrefix}}" \ + {{- end}} + {{- if .Values.syncCatalog.addK8SNamespaceSuffix}} + -add-k8s-namespace-suffix \ + {{- end}} + {{- if .Values.global.enableConsulNamespaces }} + -enable-namespaces=true \ + {{- if .Values.syncCatalog.consulNamespaces.consulDestinationNamespace }} + -consul-destination-namespace={{ .Values.syncCatalog.consulNamespaces.consulDestinationNamespace }} \ + {{- end }} + {{- if .Values.syncCatalog.consulNamespaces.mirroringK8S }} + -enable-k8s-namespace-mirroring=true \ + {{- if .Values.syncCatalog.consulNamespaces.mirroringK8SPrefix }} + -k8s-namespace-mirroring-prefix={{ .Values.syncCatalog.consulNamespaces.mirroringK8SPrefix }} \ + {{- end }} + {{- end }} + {{- if .Values.global.acls.manageSystemACLs }} + -consul-cross-namespace-acl-policy=cross-namespace-policy \ + {{- end }} + {{- end }} + {{- if .Values.syncCatalog.ingress.enabled }} + -enable-ingress=true \ + {{- if .Values.syncCatalog.ingress.loadBalancerIPs }} + -loadBalancer-ips=true \ + {{- end }} + {{- end }} + {{- if .Values.syncCatalog.syncLoadBalancerEndpoints }} + -sync-lb-services-endpoints=true \ + {{- end }} + livenessProbe: + httpGet: + path: /health/ready + port: 8080 + scheme: HTTP + failureThreshold: 3 + initialDelaySeconds: 30 + periodSeconds: 5 + successThreshold: 1 + timeoutSeconds: 5 + readinessProbe: + httpGet: + path: /health/ready + port: 8080 + scheme: HTTP + failureThreshold: 5 + initialDelaySeconds: 10 + periodSeconds: 5 + successThreshold: 1 + timeoutSeconds: 5 + {{- with .Values.syncCatalog.resources }} + resources: + {{- toYaml . | nindent 10 }} + {{- end }} + {{- if .Values.syncCatalog.priorityClassName }} + priorityClassName: {{ .Values.syncCatalog.priorityClassName | quote }} + {{- end }} + {{- if .Values.syncCatalog.nodeSelector }} + nodeSelector: + {{ tpl .Values.syncCatalog.nodeSelector . | indent 8 | trim }} + {{- end }} + {{- if .Values.syncCatalog.affinity }} + affinity: + {{ tpl .Values.syncCatalog.affinity . | indent 8 | trim }} + {{- end }} + {{- if .Values.syncCatalog.tolerations }} + tolerations: + {{ tpl .Values.syncCatalog.tolerations . | indent 8 | trim }} + {{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/sync-catalog-podsecuritypolicy.yaml b/kubernetes-vault/consul/templates/sync-catalog-podsecuritypolicy.yaml new file mode 100644 index 0000000..cc70fea --- /dev/null +++ b/kubernetes-vault/consul/templates/sync-catalog-podsecuritypolicy.yaml @@ -0,0 +1,40 @@ +{{- if (and .Values.global.enablePodSecurityPolicies (or (and (ne (.Values.syncCatalog.enabled | toString) "-") .Values.syncCatalog.enabled) (and (eq (.Values.syncCatalog.enabled | toString) "-") .Values.global.enabled))) }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "consul.fullname" . }}-sync-catalog + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: sync-catalog +spec: + privileged: false + # Required to prevent escalations to root. + allowPrivilegeEscalation: false + # This is redundant with non-root + disallow privilege escalation, + # but we can provide it for defense in depth. + requiredDropCapabilities: + - ALL + # Allow core volume types. + volumes: + - 'configMap' + - 'emptyDir' + - 'projected' + - 'secret' + - 'downwardAPI' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' + readOnlyRootFilesystem: false +{{- end }} diff --git a/kubernetes-vault/consul/templates/sync-catalog-serviceaccount.yaml b/kubernetes-vault/consul/templates/sync-catalog-serviceaccount.yaml new file mode 100644 index 0000000..deab1ad --- /dev/null +++ b/kubernetes-vault/consul/templates/sync-catalog-serviceaccount.yaml @@ -0,0 +1,24 @@ +{{- $syncEnabled := (or (and (ne (.Values.syncCatalog.enabled | toString) "-") .Values.syncCatalog.enabled) (and (eq (.Values.syncCatalog.enabled | toString) "-") .Values.global.enabled)) }} +{{- if $syncEnabled }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "consul.fullname" . }}-sync-catalog + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: sync-catalog + {{- if .Values.syncCatalog.serviceAccount.annotations }} + annotations: + {{ tpl .Values.syncCatalog.serviceAccount.annotations . | nindent 4 | trim }} + {{- end }} +{{- with .Values.global.imagePullSecrets }} +imagePullSecrets: +{{- range . }} + - name: {{ .name }} +{{- end }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/telemetry-collector-configmap.yaml b/kubernetes-vault/consul/templates/telemetry-collector-configmap.yaml new file mode 100644 index 0000000..0bf5b87 --- /dev/null +++ b/kubernetes-vault/consul/templates/telemetry-collector-configmap.yaml @@ -0,0 +1,18 @@ +{{- if (and .Values.telemetryCollector.enabled .Values.telemetryCollector.customExporterConfig) }} +# Immutable ConfigMap which saves the partition name. Attempting to update this configmap +# with a new Admin Partition name will cause the helm upgrade to fail +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "consul.fullname" . }}-telemetry-collector + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: consul-telemetry-collector +data: + config.json: |- + {{ tpl .Values.telemetryCollector.customExporterConfig . | trimAll "\"" | indent 4 }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/telemetry-collector-deployment.yaml b/kubernetes-vault/consul/templates/telemetry-collector-deployment.yaml new file mode 100644 index 0000000..7832699 --- /dev/null +++ b/kubernetes-vault/consul/templates/telemetry-collector-deployment.yaml @@ -0,0 +1,453 @@ +{{- if and .Values.telemetryCollector.enabled (not (mustHas "resource-apis" .Values.global.experiments)) }} +{{- if not .Values.telemetryCollector.image}}{{ fail "telemetryCollector.image must be set to enable consul-telemetry-collector" }}{{ end }} +{{- if not .Values.connectInject.enabled }}{{ fail "connectInject.enabled must be true" }}{{ end -}} +{{- if and .Values.global.adminPartitions.enabled (not .Values.global.enableConsulNamespaces) }}{{ fail "global.enableConsulNamespaces must be true if global.adminPartitions.enabled=true" }}{{ end }} +{{ template "consul.validateCloudSecretKeys" . }} +{{ template "consul.validateTelemetryCollectorCloud" . }} +{{ template "consul.validateTelemetryCollectorCloudSecretKeys" . }} +{{ template "consul.validateTelemetryCollectorResourceId" . }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "consul.fullname" . }}-telemetry-collector + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: consul-telemetry-collector + {{- if .Values.global.extraLabels }} + {{- toYaml .Values.global.extraLabels | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.telemetryCollector.replicas }} + selector: + matchLabels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: consul-telemetry-collector + template: + metadata: + annotations: + "consul.hashicorp.com/connect-inject": "false" + # This annotation tells the endpoints controller that this pod was injected even though it wasn't. The + # endpoints controller would then sync the endpoint into Consul + "consul.hashicorp.com/connect-inject-status": "injected" + # Signals to the endpoints controller that we should force Consul NS creation, since we bypass the mesh webhook. + "consul.hashicorp.com/telemetry-collector": "true" + # We aren't using tproxy and we don't have an original pod. This would be simpler if we made a path similar + # to gateways + "consul.hashicorp.com/connect-service-port": "metricsserver" + "consul.hashicorp.com/transparent-proxy": "false" + "consul.hashicorp.com/transparent-proxy-overwrite-probes": "false" + "consul.hashicorp.com/connect-k8s-version": {{ $.Chart.Version }} + {{- if .Values.telemetryCollector.customExporterConfig }} + # configmap checksum + "consul.hashicorp.com/config-checksum": {{ include (print $.Template.BasePath "/telemetry-collector-configmap.yaml") . | sha256sum }} + {{- end }} + # vault annotations + {{- if (and .Values.global.secretsBackend.vault.enabled .Values.global.tls.enabled) }} + "vault.hashicorp.com/agent-init-first": "true" + "vault.hashicorp.com/agent-inject": "true" + "vault.hashicorp.com/role": {{ .Values.global.secretsBackend.vault.consulCARole }} + "vault.hashicorp.com/agent-inject-secret-serverca.crt": {{ .Values.global.tls.caCert.secretName }} + "vault.hashicorp.com/agent-inject-template-serverca.crt": {{ template "consul.serverTLSCATemplate" . }} + {{- if and .Values.global.secretsBackend.vault.ca.secretName .Values.global.secretsBackend.vault.ca.secretKey }} + "vault.hashicorp.com/agent-extra-secret": "{{ .Values.global.secretsBackend.vault.ca.secretName }}" + "vault.hashicorp.com/ca-cert": "/vault/custom/{{ .Values.global.secretsBackend.vault.ca.secretKey }}" + {{- end }} + {{- if .Values.global.secretsBackend.vault.agentAnnotations }} + {{ tpl .Values.global.secretsBackend.vault.agentAnnotations . | nindent 8 | trim }} + {{- end }} + {{- if (and (.Values.global.secretsBackend.vault.vaultNamespace) (not (hasKey (default "" .Values.global.secretsBackend.vault.agentAnnotations | fromYaml) "vault.hashicorp.com/namespace")))}} + "vault.hashicorp.com/namespace": "{{ .Values.global.secretsBackend.vault.vaultNamespace }}" + {{- end }} + {{- end }} + + labels: + consul.hashicorp.com/connect-inject-managed-by: consul-k8s-endpoints-controller + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: consul-telemetry-collector + {{- if .Values.global.extraLabels }} + {{- toYaml .Values.global.extraLabels | nindent 8 }} + {{- end }} + spec: + # This needs to explicitly be consul-telemetry-collector because we look this up from each service consul-dataplane + # to forward metrics to it. + serviceAccountName: consul-telemetry-collector + initContainers: + # We're manually managing this init container instead of using the connect injector so that we don't run into + # any race conditions on the connect-injector deployment or upgrade + - name: consul-connect-init + env: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: CONSUL_NODE_NAME + value: $(NODE_NAME)-virtual + {{- include "consul.consulK8sConsulServerEnvVars" . | nindent 10 }} + # acl login info + {{- if .Values.global.acls.manageSystemACLs }} + - name: CONSUL_LOGIN_AUTH_METHOD + value: {{ template "consul.fullname" . }}-k8s-auth-method + - name: CONSUL_LOGIN_DATACENTER + value: {{ .Values.global.datacenter }} + - name: CONSUL_LOGIN_META + value: "component=consul-telemetry-collector,pod=$(NAMESPACE)/$(POD_NAME)" + {{- end }} + # service and login namespace + # this is attempting to replicate the behavior of webhooks in calculating namespace + # https://github.com/hashicorp/consul-k8s/blob/b84339050bb2c4b62b60cec96275f74952b0ac9d/control-plane/connect-inject/webhook/consul_dataplane_sidecar.go#L200 + {{- if .Values.global.enableConsulNamespaces }} + {{- if .Values.connectInject.consulNamespaces.mirroringK8S }} + - name: CONSUL_NAMESPACE + value: {{ .Values.connectInject.consulNamespaces.mirroringK8SPrefix }}{{ .Release.Namespace }} + {{- else }} + - name: CONSUL_NAMESPACE + value: {{ .Values.connectInject.consulNamespaces.consulDestinationNamespace }} + {{- end }} + {{- if .Values.global.acls.manageSystemACLs }} + {{- if .Values.connectInject.consulNamespaces.mirroringK8S }} + - name: CONSUL_LOGIN_NAMESPACE + value: default + {{- else }} + - name: CONSUL_LOGIN_NAMESPACE + value: {{ .Values.connectInject.consulNamespaces.consulDestinationNamespace }} + {{- end }} + {{- end }} + {{- end }} + command: + - /bin/sh + - -ec + - |- + exec consul-k8s-control-plane connect-init \ + -log-json={{ .Values.global.logJSON }} \ + -log-level={{ default .Values.global.logLevel .Values.telemetryCollector.logLevel }} \ + -pod-name=${POD_NAME} \ + -pod-namespace=${POD_NAMESPACE} \ + -proxy-id-file="/consul/connect-inject/proxyid" \ + -service-account-name="consul-telemetry-collector" \ + -service-name="" + + image: {{ .Values.global.imageK8S }} + {{ template "consul.imagePullPolicy" . }} + {{- if .Values.telemetryCollector.initContainer.resources }} + resources: + {{- toYaml .Values.telemetryCollector.initContainer.resources | nindent 12 }} + {{- else }} + resources: + limits: + cpu: 50m + memory: 150Mi + requests: + cpu: 50m + memory: 25Mi + {{- end }} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /consul/connect-inject + name: consul-connect-inject-data + {{- if .Values.global.tls.enabled }} + {{- if not (or (and .Values.externalServers.enabled .Values.externalServers.useSystemRoots) .Values.global.secretsBackend.vault.enabled) }} + - name: consul-ca-cert + mountPath: /consul/tls/ca + readOnly: true + {{- end }} + {{- end }} + containers: + - name: consul-telemetry-collector + image: {{ .Values.telemetryCollector.image }} + {{ template "consul.imagePullPolicy" . }} + ports: + - containerPort: 9090 + name: metrics + protocol: TCP + - containerPort: 9356 + name: metricsserver + protocol: TCP + env: + # These are mounted as secrets so that the telemetry-collector can use them when cloud is enabled. + # - the hcp-go-sdk in consul agent will already look for HCP_CLIENT_ID, HCP_CLIENT_SECRET, HCP_AUTH_URL, + # HCP_SCADA_ADDRESS, and HCP_API_HOST. so nothing more needs to be done. + # - HCP_RESOURCE_ID is created either in the global cloud section or in telemetryCollector.cloud + {{- if .Values.telemetryCollector.cloud.resourceId.secretName }} + - name: HCP_RESOURCE_ID + valueFrom: + secretKeyRef: + name: {{ .Values.telemetryCollector.cloud.resourceId.secretName }} + key: {{ .Values.telemetryCollector.cloud.resourceId.secretKey }} + {{- else if .Values.global.cloud.resourceId.secretName }} + - name: HCP_RESOURCE_ID + valueFrom: + secretKeyRef: + name: {{ .Values.global.cloud.resourceId.secretName }} + key: {{ .Values.global.cloud.resourceId.secretKey }} + {{- end }} + {{- if .Values.telemetryCollector.cloud.clientId.secretName }} + - name: HCP_CLIENT_ID + valueFrom: + secretKeyRef: + name: {{ .Values.telemetryCollector.cloud.clientId.secretName }} + key: {{ .Values.telemetryCollector.cloud.clientId.secretKey }} + {{- else if .Values.global.cloud.clientId.secretName }} + - name: HCP_CLIENT_ID + valueFrom: + secretKeyRef: + name: {{ .Values.global.cloud.clientId.secretName }} + key: {{ .Values.global.cloud.clientId.secretKey }} + {{- end }} + {{- if .Values.telemetryCollector.cloud.clientSecret.secretName }} + - name: HCP_CLIENT_SECRET + valueFrom: + secretKeyRef: + name: {{ .Values.telemetryCollector.cloud.clientSecret.secretName }} + key: {{ .Values.telemetryCollector.cloud.clientSecret.secretKey }} + {{- else if .Values.global.cloud.clientSecret.secretName }} + - name: HCP_CLIENT_SECRET + valueFrom: + secretKeyRef: + name: {{ .Values.global.cloud.clientSecret.secretName }} + key: {{ .Values.global.cloud.clientSecret.secretKey }} + {{- end}} + {{- if .Values.global.cloud.authUrl.secretName }} + - name: HCP_AUTH_URL + valueFrom: + secretKeyRef: + name: {{ .Values.global.cloud.authUrl.secretName }} + key: {{ .Values.global.cloud.authUrl.secretKey }} + {{- end}} + {{- if .Values.global.cloud.apiHost.secretName }} + - name: HCP_API_HOST + valueFrom: + secretKeyRef: + name: {{ .Values.global.cloud.apiHost.secretName }} + key: {{ .Values.global.cloud.apiHost.secretKey }} + {{- end}} + {{- if .Values.global.cloud.scadaAddress.secretName }} + - name: HCP_SCADA_ADDRESS + valueFrom: + secretKeyRef: + name: {{ .Values.global.cloud.scadaAddress.secretName }} + key: {{ .Values.global.cloud.scadaAddress.secretKey }} + {{- end}} + {{- if .Values.global.trustedCAs }} + - name: SSL_CERT_DIR + value: "/etc/ssl/certs:/trusted-cas" + {{- end }} + {{- if .Values.global.metrics.datadog.otlp.enabled }} + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + {{- if eq (.Values.global.metrics.datadog.otlp.protocol | lower ) "http" }} + - name: CO_OTEL_HTTP_ENDPOINT + value: "http://$(HOST_IP):4318" + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: "http://$(HOST_IP):4318" + {{- else if eq (.Values.global.metrics.datadog.otlp.protocol | lower) "grpc" }} + - name: CO_OTEL_HTTP_ENDPOINT + value: "http://$(HOST_IP):4317" + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: "http://$(HOST_IP):4317" + {{- end }} + {{- end }} + {{- include "consul.extraEnvironmentVars" .Values.telemetryCollector | nindent 12 }} + command: + - "/bin/sh" + - "-ec" + - | + {{- if .Values.global.trustedCAs }} + {{- range $i, $cert := .Values.global.trustedCAs }} + cat < /trusted-cas/custom-ca-{{$i}}.pem + {{- $cert | nindent 10 }} + EOF + {{- end }} + {{- end }} + + exec consul-telemetry-collector agent \ + {{- if .Values.telemetryCollector.customExporterConfig }} + -config-file-path /consul/config/config.json \ + {{ end }} + volumeMounts: + {{- if .Values.telemetryCollector.customExporterConfig }} + - name: config + mountPath: /consul/config + {{- end }} + {{- if .Values.global.trustedCAs }} + - name: trusted-cas + mountPath: /trusted-cas + readOnly: false + {{- end }} + resources: + {{- if .Values.telemetryCollector.resources }} + {{- toYaml .Values.telemetryCollector.resources | nindent 12 }} + {{- end }} + # consul-dataplane container + - name: consul-dataplane + image: "{{ .Values.global.imageConsulDataplane }}" + {{ template "consul.imagePullPolicy" . }} + command: + - consul-dataplane + args: + # addresses + {{- if .Values.externalServers.enabled }} + - -addresses={{ .Values.externalServers.hosts | first }} + {{- else }} + - -addresses={{ template "consul.fullname" . }}-server.{{ .Release.Namespace }}.svc + {{- end }} + # grpc + {{- if .Values.externalServers.enabled }} + - -grpc-port={{ .Values.externalServers.grpcPort }} + {{- else }} + - -grpc-port=8502 + {{- end }} + - -proxy-service-id-path=/consul/connect-inject/proxyid + # tls + {{- if .Values.global.tls.enabled }} + {{- if (not (and .Values.externalServers.enabled .Values.externalServers.useSystemRoots)) }} + {{- if .Values.global.secretsBackend.vault.enabled }} + - -ca-certs=/vault/secrets/serverca.crt + {{- else }} + - -ca-certs=/consul/tls/ca/tls.crt + {{- end }} + {{- end }} + {{- if and .Values.externalServers.enabled .Values.externalServers.tlsServerName }} + - -tls-server-name={{.Values.externalServers.tlsServerName }} + {{- else if .Values.global.cloud.enabled }} + - -tls-server-name=server.{{ .Values.global.datacenter}}.{{ .Values.global.domain}} + {{- end }} + {{- else }} + - -tls-disabled + {{- end }} + # credentials + {{- if .Values.global.acls.manageSystemACLs }} + - -credential-type=login + - -login-bearer-token-path=/var/run/secrets/kubernetes.io/serviceaccount/token + - -login-auth-method={{ template "consul.fullname" . }}-k8s-auth-method + {{- end }} + # service and login namespace + {{- if .Values.global.enableConsulNamespaces }} + {{- if .Values.connectInject.consulNamespaces.mirroringK8S }} + - -service-namespace={{ .Values.connectInject.consulNamespaces.mirroringK8SPrefix }}{{ .Release.Namespace }} + {{- else }} + - -service-namespace={{ .Values.connectInject.consulNamespaces.consulDestinationNamespace }} + {{- end }} + {{- if .Values.global.acls.manageSystemACLs }} + {{- if .Values.connectInject.consulNamespaces.mirroringK8S }} + - -login-namespace=default + {{- else }} + - -login-namespace={{ .Values.connectInject.consulNamespaces.consulDestinationNamespace }} + {{- end }} + {{- end }} + {{- end }} + # service and login partition + {{- if .Values.global.adminPartitions.enabled }} + - -service-partition={{ .Values.global.adminPartitions.name }} + {{- if .Values.global.acls.manageSystemACLs }} + - -login-partition={{ .Values.global.adminPartitions.name }} + {{- end }} + {{- end }} + # telemetry + {{- if .Values.global.metrics.enabled }} + - -telemetry-prom-scrape-path=/metrics + {{- end }} + - -log-level={{ default .Values.global.logLevel .Values.telemetryCollector.logLevel }} + - -log-json={{ .Values.global.logJSON }} + - -envoy-concurrency=2 + {{- if and .Values.externalServers.enabled .Values.externalServers.skipServerWatch }} + - -server-watch-disabled=true + {{- end }} + env: + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: DP_CREDENTIAL_LOGIN_META1 + value: pod=$(NAMESPACE)/$(POD_NAME) + - name: DP_CREDENTIAL_LOGIN_META2 + value: component=consul-telemetry-collector + - name: DP_SERVICE_NODE_NAME + value: $(NODE_NAME)-virtual + - name: TMPDIR + value: /consul/connect-inject + readinessProbe: + failureThreshold: 3 + initialDelaySeconds: 1 + periodSeconds: 10 + successThreshold: 1 + tcpSocket: + port: 20000 + timeoutSeconds: 1 + securityContext: + readOnlyRootFilesystem: true + runAsGroup: 5995 + runAsNonRoot: true + runAsUser: 5995 + # dataplane volume mounts + volumeMounts: + - mountPath: /consul/connect-inject + name: consul-connect-inject-data + {{- if .Values.global.tls.enabled }} + {{- if not (or (and .Values.externalServers.enabled .Values.externalServers.useSystemRoots) .Values.global.secretsBackend.vault.enabled) }} + - name: consul-ca-cert + mountPath: /consul/tls/ca + readOnly: true + {{- end }} + {{- end }} + + {{- if .Values.telemetryCollector.nodeSelector }} + nodeSelector: + {{ tpl .Values.telemetryCollector.nodeSelector . | indent 8 | trim }} + {{- end }} + {{- if .Values.telemetryCollector.priorityClassName }} + priorityClassName: {{ .Values.telemetryCollector.priorityClassName }} + {{- end }} + volumes: + - emptyDir: + medium: Memory + name: consul-connect-inject-data + {{- if .Values.global.trustedCAs }} + - name: trusted-cas + emptyDir: + medium: "Memory" + {{- end }} + {{- if .Values.global.tls.enabled }} + {{- if not (or (and .Values.externalServers.enabled .Values.externalServers.useSystemRoots) .Values.global.secretsBackend.vault.enabled) }} + - name: consul-ca-cert + secret: + {{- if .Values.global.tls.caCert.secretName }} + secretName: {{ .Values.global.tls.caCert.secretName }} + {{- else }} + secretName: {{ template "consul.fullname" . }}-ca-cert + {{- end }} + items: + - key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }} + path: tls.crt + {{- end }} + {{- end }} + - name: config + configMap: + name: {{ template "consul.fullname" . }}-telemetry-collector +{{- end }} diff --git a/kubernetes-vault/consul/templates/telemetry-collector-podsecuritypolicy.yaml b/kubernetes-vault/consul/templates/telemetry-collector-podsecuritypolicy.yaml new file mode 100644 index 0000000..f4c05a2 --- /dev/null +++ b/kubernetes-vault/consul/templates/telemetry-collector-podsecuritypolicy.yaml @@ -0,0 +1,42 @@ +{{- if and .Values.global.enablePodSecurityPolicies .Values.telemetryCollector.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "consul.fullname" . }}-telemetry-collector + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: telemetry-collector +spec: + privileged: false + # Required to prevent escalations to root. + allowPrivilegeEscalation: false + # This is redundant with non-root + disallow privilege escalation, + # but we can provide it for defense in depth. + requiredDropCapabilities: + - ALL + defaultAddCapabilities: + - NET_BIND_SERVICE + # Allow core volume types. + volumes: + - 'configMap' + - 'emptyDir' + - 'projected' + - 'secret' + - 'downwardAPI' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' + readOnlyRootFilesystem: false +{{- end }} diff --git a/kubernetes-vault/consul/templates/telemetry-collector-role.yaml b/kubernetes-vault/consul/templates/telemetry-collector-role.yaml new file mode 100644 index 0000000..f893732 --- /dev/null +++ b/kubernetes-vault/consul/templates/telemetry-collector-role.yaml @@ -0,0 +1,21 @@ +{{- if and .Values.global.enablePodSecurityPolicies .Values.telemetryCollector.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "consul.fullname" . }}-telemetry-collector + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: consul-telemetry-collector +rules: + - apiGroups: ["policy"] + resources: ["podsecuritypolicies"] + resourceNames: + - {{ template "consul.fullname" . }}-telemetry-collector + verbs: + - use +{{- end }} + diff --git a/kubernetes-vault/consul/templates/telemetry-collector-rolebinding.yaml b/kubernetes-vault/consul/templates/telemetry-collector-rolebinding.yaml new file mode 100644 index 0000000..1f9a896 --- /dev/null +++ b/kubernetes-vault/consul/templates/telemetry-collector-rolebinding.yaml @@ -0,0 +1,21 @@ +{{- if and .Values.global.enablePodSecurityPolicies .Values.telemetryCollector.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "consul.fullname" . }}-telemetry-collector + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: consul-telemetry-collector +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "consul.fullname" . }}-telemetry-collector +subjects: + - kind: ServiceAccount + name: {{ template "consul.fullname" . }}-telemetry-collector +{{- end }} + diff --git a/kubernetes-vault/consul/templates/telemetry-collector-service.yaml b/kubernetes-vault/consul/templates/telemetry-collector-service.yaml new file mode 100644 index 0000000..266c80b --- /dev/null +++ b/kubernetes-vault/consul/templates/telemetry-collector-service.yaml @@ -0,0 +1,24 @@ +{{- if .Values.telemetryCollector.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: consul-telemetry-collector + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: consul-telemetry-collector + {{ if .Values.telemetryCollector.service.annotations }} + annotations: + {{ tpl .Values.telemetryCollector.service.annotations . | nindent 4 | trim }} + {{- end }} +spec: + type: ClusterIP + ports: + - port: 9356 + targetPort: 9356 + selector: + app: consul + component: consul-telemetry-collector +{{- end }} \ No newline at end of file diff --git a/kubernetes-vault/consul/templates/telemetry-collector-serviceaccount.yaml b/kubernetes-vault/consul/templates/telemetry-collector-serviceaccount.yaml new file mode 100644 index 0000000..fca58ee --- /dev/null +++ b/kubernetes-vault/consul/templates/telemetry-collector-serviceaccount.yaml @@ -0,0 +1,23 @@ +{{- if .Values.telemetryCollector.enabled }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: consul-telemetry-collector + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: consul-telemetry-collector + {{- if .Values.telemetryCollector.serviceAccount.annotations }} + annotations: + {{ tpl .Values.telemetryCollector.serviceAccount.annotations . | nindent 4 | trim }} + {{- end }} +automountServiceAccountToken: true +{{- with .Values.global.imagePullSecrets }} +imagePullSecrets: +{{- range . }} + - name: {{ .name }} +{{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/kubernetes-vault/consul/templates/telemetry-collector-v2-deployment.yaml b/kubernetes-vault/consul/templates/telemetry-collector-v2-deployment.yaml new file mode 100644 index 0000000..09f4a2d --- /dev/null +++ b/kubernetes-vault/consul/templates/telemetry-collector-v2-deployment.yaml @@ -0,0 +1,415 @@ +{{- if and .Values.telemetryCollector.enabled (mustHas "resource-apis" .Values.global.experiments) }} +{{- if not .Values.telemetryCollector.image}}{{ fail "telemetryCollector.image must be set to enable consul-telemetry-collector" }}{{ end }} +{{- if not .Values.connectInject.enabled }}{{ fail "connectInject.enabled must be true" }}{{ end -}} +{{- if and .Values.global.adminPartitions.enabled (not .Values.global.enableConsulNamespaces) }}{{ fail "global.enableConsulNamespaces must be true if global.adminPartitions.enabled=true" }}{{ end }} +{{ template "consul.validateCloudSecretKeys" . }} +{{ template "consul.validateTelemetryCollectorCloud" . }} +{{ template "consul.validateTelemetryCollectorCloudSecretKeys" . }} +{{ template "consul.validateTelemetryCollectorResourceId" . }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "consul.fullname" . }}-telemetry-collector + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: consul-telemetry-collector + {{- if .Values.global.extraLabels }} + {{- toYaml .Values.global.extraLabels | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.telemetryCollector.replicas }} + selector: + matchLabels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: consul-telemetry-collector + template: + metadata: + annotations: + "consul.hashicorp.com/mesh-inject": "false" + # This annotation tells the pod controller that this pod was injected even though it wasn't. + # This ensures the pod controller will sync a workload for the pod into Consul + "consul.hashicorp.com/mesh-inject-status": "injected" + # We aren't using tproxy and we don't have an original pod. This would be simpler if we made a path similar + # to gateways + "consul.hashicorp.com/transparent-proxy": "false" + "consul.hashicorp.com/transparent-proxy-overwrite-probes": "false" + "consul.hashicorp.com/consul-k8s-version": {{ $.Chart.Version }} + {{- if .Values.telemetryCollector.customExporterConfig }} + # configmap checksum + "consul.hashicorp.com/config-checksum": {{ include (print $.Template.BasePath "/telemetry-collector-configmap.yaml") . | sha256sum }} + {{- end }} + # vault annotations + {{- if (and .Values.global.secretsBackend.vault.enabled .Values.global.tls.enabled) }} + "vault.hashicorp.com/agent-init-first": "true" + "vault.hashicorp.com/agent-inject": "true" + "vault.hashicorp.com/role": {{ .Values.global.secretsBackend.vault.consulCARole }} + "vault.hashicorp.com/agent-inject-secret-serverca.crt": {{ .Values.global.tls.caCert.secretName }} + "vault.hashicorp.com/agent-inject-template-serverca.crt": {{ template "consul.serverTLSCATemplate" . }} + {{- if and .Values.global.secretsBackend.vault.ca.secretName .Values.global.secretsBackend.vault.ca.secretKey }} + "vault.hashicorp.com/agent-extra-secret": "{{ .Values.global.secretsBackend.vault.ca.secretName }}" + "vault.hashicorp.com/ca-cert": "/vault/custom/{{ .Values.global.secretsBackend.vault.ca.secretKey }}" + {{- end }} + {{- if .Values.global.secretsBackend.vault.agentAnnotations }} + {{ tpl .Values.global.secretsBackend.vault.agentAnnotations . | nindent 8 | trim }} + {{- end }} + {{- if (and (.Values.global.secretsBackend.vault.vaultNamespace) (not (hasKey (default "" .Values.global.secretsBackend.vault.agentAnnotations | fromYaml) "vault.hashicorp.com/namespace")))}} + "vault.hashicorp.com/namespace": "{{ .Values.global.secretsBackend.vault.vaultNamespace }}" + {{- end }} + {{- end }} + + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: consul-telemetry-collector + {{- if .Values.global.extraLabels }} + {{- toYaml .Values.global.extraLabels | nindent 8 }} + {{- end }} + spec: + # This needs to explicitly be consul-telemetry-collector because we look this up from each service consul-dataplane + # to forward metrics to it. + serviceAccountName: consul-telemetry-collector + initContainers: + # We're manually managing this init container instead of using the mesh injector so that we don't run into + # any race conditions on the mesh-injector deployment or upgrade + - name: consul-mesh-init + env: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + # acl login info + {{- if .Values.global.acls.manageSystemACLs }} + - name: CONSUL_LOGIN_AUTH_METHOD + value: {{ template "consul.fullname" . }}-k8s-auth-method + - name: CONSUL_LOGIN_DATACENTER + value: {{ .Values.global.datacenter }} + - name: CONSUL_LOGIN_META + value: "component=consul-telemetry-collector,pod=$(NAMESPACE)/$(POD_NAME)" + {{- end }} + # service and login namespace + # this is attempting to replicate the behavior of webhooks in calculating namespace + # https://github.com/hashicorp/consul-k8s/blob/b84339050bb2c4b62b60cec96275f74952b0ac9d/control-plane/connect-inject/webhook/consul_dataplane_sidecar.go#L200 + {{- if .Values.global.enableConsulNamespaces }} + {{- if .Values.connectInject.consulNamespaces.mirroringK8S }} + - name: CONSUL_NAMESPACE + value: {{ .Values.connectInject.consulNamespaces.mirroringK8SPrefix }}{{ .Release.Namespace }} + {{- else }} + - name: CONSUL_NAMESPACE + value: {{ .Values.connectInject.consulNamespaces.consulDestinationNamespace }} + {{- end }} + {{- if .Values.global.acls.manageSystemACLs }} + {{- if .Values.connectInject.consulNamespaces.mirroringK8S }} + - name: CONSUL_LOGIN_NAMESPACE + value: "default" + {{- else }} + - name: CONSUL_LOGIN_NAMESPACE + value: {{ .Values.connectInject.consulNamespaces.consulDestinationNamespace }} + {{- end }} + {{- end }} + {{- end }} + command: + - /bin/sh + - -ec + - |- + exec consul-k8s-control-plane mesh-init -proxy-name=${POD_NAME} \ + -log-level={{ default .Values.global.logLevel .Values.telemetryCollector.logLevel }} \ + -log-json={{ .Values.global.logJSON }} + + image: {{ .Values.global.imageK8S }} + imagePullPolicy: IfNotPresent + {{- if .Values.telemetryCollector.initContainer.resources }} + resources: + {{- toYaml .Values.telemetryCollector.initContainer.resources | nindent 12 }} + {{- else }} + resources: + limits: + cpu: 50m + memory: 150Mi + requests: + cpu: 50m + memory: 25Mi + {{- end }} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /consul/mesh-inject + name: consul-mesh-inject-data + {{- if .Values.global.tls.enabled }} + {{- if not (or (and .Values.externalServers.enabled .Values.externalServers.useSystemRoots) .Values.global.secretsBackend.vault.enabled) }} + - name: consul-ca-cert + mountPath: /consul/tls/ca + readOnly: true + {{- end }} + {{- end }} + containers: + - name: consul-telemetry-collector + image: {{ .Values.telemetryCollector.image }} + imagePullPolicy: {{ .Values.global.imagePullPolicy }} + ports: + - containerPort: 9090 + name: metrics + protocol: TCP + - containerPort: 9356 + name: metricsserver + protocol: TCP + env: + # These are mounted as secrets so that the telemetry-collector can use them when cloud is enabled. + # - the hcp-go-sdk in consul agent will already look for HCP_CLIENT_ID, HCP_CLIENT_SECRET, HCP_AUTH_URL, + # HCP_SCADA_ADDRESS, and HCP_API_HOST. so nothing more needs to be done. + # - HCP_RESOURCE_ID is created either in the global cloud section or in telemetryCollector.cloud + {{- if .Values.telemetryCollector.cloud.resourceId.secretName }} + - name: HCP_RESOURCE_ID + valueFrom: + secretKeyRef: + name: {{ .Values.telemetryCollector.cloud.resourceId.secretName }} + key: {{ .Values.telemetryCollector.cloud.resourceId.secretKey }} + {{- else if .Values.global.cloud.resourceId.secretName }} + - name: HCP_RESOURCE_ID + valueFrom: + secretKeyRef: + name: {{ .Values.global.cloud.resourceId.secretName }} + key: {{ .Values.global.cloud.resourceId.secretKey }} + {{- end }} + {{- if .Values.telemetryCollector.cloud.clientId.secretName }} + - name: HCP_CLIENT_ID + valueFrom: + secretKeyRef: + name: {{ .Values.telemetryCollector.cloud.clientId.secretName }} + key: {{ .Values.telemetryCollector.cloud.clientId.secretKey }} + {{- else if .Values.global.cloud.clientId.secretName }} + - name: HCP_CLIENT_ID + valueFrom: + secretKeyRef: + name: {{ .Values.global.cloud.clientId.secretName }} + key: {{ .Values.global.cloud.clientId.secretKey }} + {{- end }} + {{- if .Values.telemetryCollector.cloud.clientSecret.secretName }} + - name: HCP_CLIENT_SECRET + valueFrom: + secretKeyRef: + name: {{ .Values.telemetryCollector.cloud.clientSecret.secretName }} + key: {{ .Values.telemetryCollector.cloud.clientSecret.secretKey }} + {{- else if .Values.global.cloud.clientSecret.secretName }} + - name: HCP_CLIENT_SECRET + valueFrom: + secretKeyRef: + name: {{ .Values.global.cloud.clientSecret.secretName }} + key: {{ .Values.global.cloud.clientSecret.secretKey }} + {{- end}} + {{- if .Values.global.cloud.authUrl.secretName }} + - name: HCP_AUTH_URL + valueFrom: + secretKeyRef: + name: {{ .Values.global.cloud.authUrl.secretName }} + key: {{ .Values.global.cloud.authUrl.secretKey }} + {{- end}} + {{- if .Values.global.cloud.apiHost.secretName }} + - name: HCP_API_HOST + valueFrom: + secretKeyRef: + name: {{ .Values.global.cloud.apiHost.secretName }} + key: {{ .Values.global.cloud.apiHost.secretKey }} + {{- end}} + {{- if .Values.global.cloud.scadaAddress.secretName }} + - name: HCP_SCADA_ADDRESS + valueFrom: + secretKeyRef: + name: {{ .Values.global.cloud.scadaAddress.secretName }} + key: {{ .Values.global.cloud.scadaAddress.secretKey }} + {{- end}} + {{- if .Values.global.trustedCAs }} + - name: SSL_CERT_DIR + value: "/etc/ssl/certs:/trusted-cas" + {{- end }} + {{- include "consul.extraEnvironmentVars" .Values.telemetryCollector | nindent 12 }} + command: + - "/bin/sh" + - "-ec" + - | + {{- if .Values.global.trustedCAs }} + {{- range $i, $cert := .Values.global.trustedCAs }} + cat < /trusted-cas/custom-ca-{{$i}}.pem + {{- $cert | nindent 10 }} + EOF + {{- end }} + {{- end }} + + exec consul-telemetry-collector agent \ + {{- if .Values.telemetryCollector.customExporterConfig }} + -config-file-path /consul/config/config.json \ + {{ end }} + volumeMounts: + {{- if .Values.telemetryCollector.customExporterConfig }} + - name: config + mountPath: /consul/config + {{- end }} + {{- if .Values.global.trustedCAs }} + - name: trusted-cas + mountPath: /trusted-cas + readOnly: false + {{- end }} + resources: + {{- if .Values.telemetryCollector.resources }} + {{- toYaml .Values.telemetryCollector.resources | nindent 12 }} + {{- end }} + # consul-dataplane container + - name: consul-dataplane + image: "{{ .Values.global.imageConsulDataplane }}" + imagePullPolicy: IfNotPresent + command: + - consul-dataplane + args: + # addresses + {{- if .Values.externalServers.enabled }} + - -addresses={{ .Values.externalServers.hosts | first }} + {{- else }} + - -addresses={{ template "consul.fullname" . }}-server.{{ .Release.Namespace }}.svc + {{- end }} + # grpc + {{- if .Values.externalServers.enabled }} + - -grpc-port={{ .Values.externalServers.grpcPort }} + {{- else }} + - -grpc-port=8502 + {{- end }} + # tls + {{- if .Values.global.tls.enabled }} + {{- if (not (and .Values.externalServers.enabled .Values.externalServers.useSystemRoots)) }} + {{- if .Values.global.secretsBackend.vault.enabled }} + - -ca-certs=/vault/secrets/serverca.crt + {{- else }} + - -ca-certs=/consul/tls/ca/tls.crt + {{- end }} + {{- end }} + {{- if and .Values.externalServers.enabled .Values.externalServers.tlsServerName }} + - -tls-server-name={{.Values.externalServers.tlsServerName }} + {{- else if .Values.global.cloud.enabled }} + - -tls-server-name=server.{{ .Values.global.datacenter}}.{{ .Values.global.domain}} + {{- end }} + {{- else }} + - -tls-disabled + {{- end }} + # credentials + {{- if .Values.global.acls.manageSystemACLs }} + - -credential-type=login + - -login-bearer-token-path=/var/run/secrets/kubernetes.io/serviceaccount/token + - -login-auth-method={{ template "consul.fullname" . }}-k8s-auth-method + {{- end }} + # service and login namespace + {{- if .Values.global.enableConsulNamespaces }} + {{- if .Values.connectInject.consulNamespaces.mirroringK8S }} + - -service-namespace={{ .Values.connectInject.consulNamespaces.mirroringK8SPrefix }}{{ .Release.Namespace }} + {{- else }} + - -service-namespace={{ .Values.connectInject.consulNamespaces.consulDestinationNamespace }} + {{- end }} + {{- if .Values.global.acls.manageSystemACLs }} + {{- if .Values.connectInject.consulNamespaces.mirroringK8S }} + - -login-namespace=default + {{- else }} + - -login-namespace={{ .Values.connectInject.consulNamespaces.consulDestinationNamespace }} + {{- end }} + {{- end }} + {{- end }} + # service and login partition + {{- if .Values.global.adminPartitions.enabled }} + - -service-partition={{ .Values.global.adminPartitions.name }} + {{- if .Values.global.acls.manageSystemACLs }} + - -login-partition={{ .Values.global.adminPartitions.name }} + {{- end }} + {{- end }} + # telemetry + {{- if .Values.global.metrics.enabled }} + - -telemetry-prom-scrape-path=/metrics + {{- end }} + - -log-level={{ default .Values.global.logLevel .Values.telemetryCollector.logLevel }} + - -log-json={{ .Values.global.logJSON }} + - -envoy-concurrency=2 + {{- if and .Values.externalServers.enabled .Values.externalServers.skipServerWatch }} + - -server-watch-disabled=true + {{- end }} + env: + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: DP_PROXY_ID + value: $(POD_NAME) + - name: DP_CREDENTIAL_LOGIN_META1 + value: pod=$(NAMESPACE)/$(POD_NAME) + - name: DP_CREDENTIAL_LOGIN_META2 + value: component=consul-telemetry-collector + - name: TMPDIR + value: /consul/mesh-inject + readinessProbe: + failureThreshold: 3 + initialDelaySeconds: 1 + periodSeconds: 10 + successThreshold: 1 + tcpSocket: + port: 20000 + timeoutSeconds: 1 + securityContext: + readOnlyRootFilesystem: true + runAsGroup: 5995 + runAsNonRoot: true + runAsUser: 5995 + # dataplane volume mounts + volumeMounts: + - mountPath: /consul/mesh-inject + name: consul-mesh-inject-data + {{- if .Values.global.tls.enabled }} + {{- if not (or (and .Values.externalServers.enabled .Values.externalServers.useSystemRoots) .Values.global.secretsBackend.vault.enabled) }} + - name: consul-ca-cert + mountPath: /consul/tls/ca + readOnly: true + {{- end }} + {{- end }} + + {{- if .Values.telemetryCollector.nodeSelector }} + nodeSelector: + {{ tpl .Values.telemetryCollector.nodeSelector . | indent 8 | trim }} + {{- end }} + {{- if .Values.telemetryCollector.priorityClassName }} + priorityClassName: {{ .Values.telemetryCollector.priorityClassName }} + {{- end }} + volumes: + - emptyDir: + medium: Memory + name: consul-mesh-inject-data + {{- if .Values.global.trustedCAs }} + - name: trusted-cas + emptyDir: + medium: "Memory" + {{- end }} + {{- if .Values.global.tls.enabled }} + {{- if not (or (and .Values.externalServers.enabled .Values.externalServers.useSystemRoots) .Values.global.secretsBackend.vault.enabled) }} + - name: consul-ca-cert + secret: + {{- if .Values.global.tls.caCert.secretName }} + secretName: {{ .Values.global.tls.caCert.secretName }} + {{- else }} + secretName: {{ template "consul.fullname" . }}-ca-cert + {{- end }} + items: + - key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }} + path: tls.crt + {{- end }} + {{- end }} + - name: config + configMap: + name: {{ template "consul.fullname" . }}-telemetry-collector +{{- end }} diff --git a/kubernetes-vault/consul/templates/terminating-gateways-deployment.yaml b/kubernetes-vault/consul/templates/terminating-gateways-deployment.yaml new file mode 100644 index 0000000..c497097 --- /dev/null +++ b/kubernetes-vault/consul/templates/terminating-gateways-deployment.yaml @@ -0,0 +1,356 @@ +{{- if .Values.terminatingGateways.enabled }} +{{- if not .Values.connectInject.enabled }}{{ fail "connectInject.enabled must be true" }}{{ end -}} +{{- if and .Values.global.adminPartitions.enabled (not .Values.global.enableConsulNamespaces) }}{{ fail "global.enableConsulNamespaces must be true if global.adminPartitions.enabled=true" }}{{ end }} +{{ template "consul.validateRequiredCloudSecretsExist" . }} +{{ template "consul.validateCloudSecretKeys" . }} + +{{- $root := . }} +{{- $defaults := .Values.terminatingGateways.defaults }} +{{- $names := dict }} + +{{- $gateways := .Values.terminatingGateways.gateways }} +{{- range $outerTerminatingIndex, $outerTerminatingVal := $gateways }} + +{{- range $innerTerminatingIndex, $innerTerminatingVal := $gateways }} +{{- if (and (ne $outerTerminatingIndex $innerTerminatingIndex) (eq $outerTerminatingVal.name $innerTerminatingVal.name)) }} +{{ fail (cat "terminating gateways must have unique names but found duplicate name" $innerTerminatingVal.name) }} +{{ end -}} +{{ end -}} + +{{- range $outerIngressIndex, $outerIngressVal := $root.Values.ingressGateways.gateways }} +{{- if (eq $outerTerminatingVal.name $outerIngressVal.name) }} +{{ fail (cat "terminating gateways cannot have duplicate names of any ingress gateways but found duplicate name" $outerTerminatingVal.name) }} +{{ end -}} +{{ end -}} +{{ end -}} + +{{- range .Values.terminatingGateways.gateways }} + +{{- if empty .name }} +# Check that name is not empty +{{ fail "Terminating gateway names cannot be empty"}} +{{ end -}} +{{- if hasKey $names .name }} +# Check that the name doesn't already exist +{{ fail "Terminating gateway names must be unique"}} +{{ end -}} +{{- /* Add the gateway name to the $names dict to ensure uniqueness */ -}} +{{- $_ := set $names .name .name }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "consul.fullname" $root }}-{{ .name }} + namespace: {{ $root.Release.Namespace }} + labels: + app: {{ template "consul.name" $root }} + chart: {{ template "consul.chart" $root }} + heritage: {{ $root.Release.Service }} + release: {{ $root.Release.Name }} + component: terminating-gateway + terminating-gateway-name: {{ template "consul.fullname" $root }}-{{ .name }} + {{- if $root.Values.global.extraLabels }} + {{- toYaml $root.Values.global.extraLabels | nindent 4 }} + {{- end }} +spec: + replicas: {{ default $defaults.replicas .replicas }} + selector: + matchLabels: + app: {{ template "consul.name" $root }} + chart: {{ template "consul.chart" $root }} + heritage: {{ $root.Release.Service }} + release: {{ $root.Release.Name }} + component: terminating-gateway + terminating-gateway-name: {{ template "consul.fullname" $root }}-{{ .name }} + template: + metadata: + labels: + app: {{ template "consul.name" $root }} + chart: {{ template "consul.chart" $root }} + heritage: {{ $root.Release.Service }} + release: {{ $root.Release.Name }} + component: terminating-gateway + terminating-gateway-name: {{ template "consul.fullname" $root }}-{{ .name }} + consul.hashicorp.com/connect-inject-managed-by: consul-k8s-endpoints-controller + {{- if $root.Values.global.extraLabels }} + {{- toYaml $root.Values.global.extraLabels | nindent 8 }} + {{- end }} + annotations: + "consul.hashicorp.com/connect-inject": "false" + "consul.hashicorp.com/mesh-inject": "false" + "consul.hashicorp.com/gateway-kind": "terminating-gateway" + "consul.hashicorp.com/gateway-consul-service-name": "{{ .name }}" + {{- if $root.Values.global.enableConsulNamespaces }} + "consul.hashicorp.com/gateway-namespace": {{ (default $defaults.consulNamespace .consulNamespace) }} + {{- end }} + {{- if (and $root.Values.global.secretsBackend.vault.enabled $root.Values.global.tls.enabled) }} + "vault.hashicorp.com/agent-init-first": "true" + "vault.hashicorp.com/agent-inject": "true" + "vault.hashicorp.com/role": {{ $root.Values.global.secretsBackend.vault.consulCARole }} + "vault.hashicorp.com/agent-inject-secret-serverca.crt": {{ $root.Values.global.tls.caCert.secretName }} + "vault.hashicorp.com/agent-inject-template-serverca.crt": {{ template "consul.serverTLSCATemplate" $root }} + {{- if and $root.Values.global.secretsBackend.vault.ca.secretName $root.Values.global.secretsBackend.vault.ca.secretKey }} + "vault.hashicorp.com/agent-extra-secret": {{ $root.Values.global.secretsBackend.vault.ca.secretName }} + "vault.hashicorp.com/ca-cert": /vault/custom/{{ $root.Values.global.secretsBackend.vault.ca.secretKey }} + {{- end }} + {{- if $root.Values.global.secretsBackend.vault.agentAnnotations }} + {{ tpl $root.Values.global.secretsBackend.vault.agentAnnotations $root | nindent 8 | trim }} + {{- end }} + {{- if (and ($root.Values.global.secretsBackend.vault.vaultNamespace) (not (hasKey (default "" $root.Values.global.secretsBackend.vault.agentAnnotations | fromYaml) "vault.hashicorp.com/namespace")))}} + "vault.hashicorp.com/namespace": "{{ $root.Values.global.secretsBackend.vault.vaultNamespace }}" + {{- end }} + {{- end }} + {{- if (and $root.Values.global.metrics.enabled $root.Values.global.metrics.enableGatewayMetrics) }} + "prometheus.io/scrape": "true" + {{- if not (hasKey (default "" $defaults.annotations | fromYaml) "prometheus.io/path")}} + "prometheus.io/path": "/metrics" + {{- end }} + "prometheus.io/port": "20200" + {{- end }} + {{- if $defaults.annotations }} + # We allow both default annotations and gateway-specific annotations + {{- tpl $defaults.annotations $root | nindent 8 }} + {{- end }} + {{- if .annotations }} + {{- tpl .annotations $root | nindent 8 }} + {{- end }} + spec: + {{- if (or $defaults.affinity .affinity) }} + affinity: + {{ tpl (default $defaults.affinity .affinity) $root | nindent 8 | trim }} + {{- end }} + {{- if (or $defaults.tolerations .tolerations) }} + tolerations: + {{ tpl (default $defaults.tolerations .tolerations) $root | nindent 8 | trim }} + {{- end }} + {{- if (or $defaults.topologySpreadConstraints .topologySpreadConstraints) }} + topologySpreadConstraints: + {{ tpl (default $defaults.topologySpreadConstraints .topologySpreadConstraints) $root | nindent 8 | trim }} + {{- end }} + terminationGracePeriodSeconds: 10 + serviceAccountName: {{ template "consul.fullname" $root }}-{{ .name }} + volumes: + - name: tmp + emptyDir: + medium: "Memory" + - name: consul-service + emptyDir: + medium: "Memory" + {{- range (default $defaults.extraVolumes .extraVolumes) }} + - name: userconfig-{{ .name }} + {{ .type }}: + {{- if (eq .type "configMap") }} + name: {{ .name }} + {{- else if (eq .type "secret") }} + secretName: {{ .name }} + {{- end }} + {{- with .items }} + items: + {{- range . }} + - key: {{.key}} + path: {{.path}} + {{- end }} + {{- end }} + {{- end }} + {{- if $root.Values.global.tls.enabled }} + {{- if not (or (and $root.Values.externalServers.enabled $root.Values.externalServers.useSystemRoots) ($root.Values.global.secretsBackend.vault.enabled)) }} + - name: consul-ca-cert + secret: + {{- if $root.Values.global.tls.caCert.secretName }} + secretName: {{ $root.Values.global.tls.caCert.secretName }} + {{- else }} + secretName: {{ template "consul.fullname" $root }}-ca-cert + {{- end }} + items: + - key: {{ default "tls.crt" $root.Values.global.tls.caCert.secretKey }} + path: tls.crt + {{- end }} + {{- end }} + initContainers: + # terminating-gateway-init registers the terminating gateway service with Consul. + - name: terminating-gateway-init + image: {{ $root.Values.global.imageK8S }} + {{ template "consul.imagePullPolicy" $root }} + {{- include "consul.restrictedSecurityContext" $ | nindent 10 }} + env: + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + {{- include "consul.consulK8sConsulServerEnvVars" $root | nindent 10 }} + {{- if $root.Values.global.enableConsulNamespaces }} + - name: CONSUL_NAMESPACE + value: {{ (default $defaults.consulNamespace .consulNamespace) }} + {{- end }} + {{- if $root.Values.global.acls.manageSystemACLs }} + - name: CONSUL_LOGIN_AUTH_METHOD + value: {{ template "consul.fullname" $root }}-k8s-component-auth-method + - name: CONSUL_LOGIN_DATACENTER + value: {{ $root.Values.global.datacenter }} + - name: CONSUL_LOGIN_META + value: "component=terminating-gateway,pod=$(NAMESPACE)/$(POD_NAME)" + {{- end }} + - name: CONSUL_NODE_NAME + value: $(NODE_NAME)-virtual + command: + - "/bin/sh" + - "-ec" + - | + exec consul-k8s-control-plane connect-init -pod-name=${POD_NAME} -pod-namespace=${NAMESPACE} \ + -gateway-kind="terminating-gateway" \ + -proxy-id-file=/consul/service/proxy-id \ + -service-name={{ .name }} \ + -log-level={{ default $root.Values.global.logLevel $root.Values.terminatingGateways.logLevel }} \ + -log-json={{ $root.Values.global.logJSON }} + volumeMounts: + - name: tmp + mountPath: /tmp + - name: consul-service + mountPath: /consul/service + {{- if $root.Values.global.tls.enabled }} + {{- if not (or (and $root.Values.externalServers.enabled $root.Values.externalServers.useSystemRoots) ($root.Values.global.secretsBackend.vault.enabled)) }} + - name: consul-ca-cert + mountPath: /consul/tls/ca + readOnly: true + {{- end }} + {{- end }} + resources: + requests: + memory: "50Mi" + cpu: "50m" + limits: + memory: "50Mi" + cpu: "50m" + containers: + - name: terminating-gateway + image: {{ $root.Values.global.imageConsulDataplane | quote }} + {{ template "consul.imagePullPolicy" $root }} + {{- include "consul.restrictedSecurityContext" $ | nindent 10 }} + volumeMounts: + - name: tmp + mountPath: /tmp + - name: consul-service + mountPath: /consul/service + readOnly: true + {{- if $root.Values.global.tls.enabled }} + {{- if not (or (and $root.Values.externalServers.enabled $root.Values.externalServers.useSystemRoots) ($root.Values.global.secretsBackend.vault.enabled)) }} + - name: consul-ca-cert + mountPath: /consul/tls/ca + readOnly: true + {{- end }} + {{- end }} + {{- range (default $defaults.extraVolumes .extraVolumes) }} + - name: userconfig-{{ .name }} + readOnly: true + mountPath: /consul/userconfig/{{ .name }} + {{- end }} + {{- if (default $defaults.resources .resources) }} + resources: {{ toYaml (default $defaults.resources .resources) | nindent 12 }} + {{- end }} + env: + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: DP_CREDENTIAL_LOGIN_META1 + value: pod=$(NAMESPACE)/$(POD_NAME) + - name: DP_CREDENTIAL_LOGIN_META2 + value: component=terminating-gateway + - name: DP_SERVICE_NODE_NAME + value: $(NODE_NAME)-virtual + command: + - consul-dataplane + args: + {{- if $root.Values.externalServers.enabled }} + - -addresses={{ $root.Values.externalServers.hosts | first }} + {{- else }} + - -addresses={{ template "consul.fullname" $root }}-server.{{ $root.Release.Namespace }}.svc + {{- end }} + {{- if $root.Values.externalServers.enabled }} + - -grpc-port={{ $root.Values.externalServers.grpcPort }} + {{- else }} + - -grpc-port=8502 + {{- end }} + - -proxy-service-id-path=/consul/service/proxy-id + {{- if $root.Values.global.enableConsulNamespaces }} + - -service-namespace={{ (default $defaults.consulNamespace .consulNamespace) }} + {{- end }} + {{- if and $root.Values.global.tls.enabled }} + {{- if (not (and $root.Values.externalServers.enabled $root.Values.externalServers.useSystemRoots)) }} + {{- if $root.Values.global.secretsBackend.vault.enabled }} + - -ca-certs=/vault/secrets/serverca.crt + {{- else }} + - -ca-certs=/consul/tls/ca/tls.crt + {{- end }} + {{- end }} + {{- if and $root.Values.externalServers.enabled $root.Values.externalServers.tlsServerName }} + - -tls-server-name={{$root.Values.externalServers.tlsServerName }} + {{- else if $root.Values.global.cloud.enabled }} + - -tls-server-name=server.{{ $root.Values.global.datacenter}}.{{ $root.Values.global.domain}} + {{- end }} + {{- else }} + - -tls-disabled + {{- end }} + {{- if $root.Values.global.acls.manageSystemACLs }} + - -credential-type=login + - -login-bearer-token-path=/var/run/secrets/kubernetes.io/serviceaccount/token + - -login-auth-method={{ template "consul.fullname" $root }}-k8s-component-auth-method + {{- if $root.Values.global.adminPartitions.enabled }} + - -login-partition={{ $root.Values.global.adminPartitions.name }} + {{- end }} + {{- end }} + {{- if $root.Values.global.adminPartitions.enabled }} + - -service-partition={{ $root.Values.global.adminPartitions.name }} + {{- end }} + - -log-level={{ default $root.Values.global.logLevel $root.Values.terminatingGateways.logLevel }} + - -log-json={{ $root.Values.global.logJSON }} + {{- if (and $root.Values.global.metrics.enabled $root.Values.global.metrics.enableGatewayMetrics) }} + - -telemetry-prom-scrape-path=/metrics + {{- end }} + {{- if and $root.Values.externalServers.enabled $root.Values.externalServers.skipServerWatch }} + - -server-watch-disabled=true + {{- end }} + livenessProbe: + tcpSocket: + port: 8443 + failureThreshold: 3 + initialDelaySeconds: 30 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + readinessProbe: + tcpSocket: + port: 8443 + failureThreshold: 3 + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + ports: + - name: gateway + containerPort: 8443 + {{- if (default $defaults.priorityClassName .priorityClassName) }} + priorityClassName: {{ (default $defaults.priorityClassName .priorityClassName) | quote }} + {{- end }} + {{- if (default $defaults.nodeSelector .nodeSelector) }} + nodeSelector: + {{ tpl (default $defaults.nodeSelector .nodeSelector) $root | indent 8 | trim }} + {{- end }} +--- +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/terminating-gateways-podsecuritypolicy.yaml b/kubernetes-vault/consul/templates/terminating-gateways-podsecuritypolicy.yaml new file mode 100644 index 0000000..7307fb8 --- /dev/null +++ b/kubernetes-vault/consul/templates/terminating-gateways-podsecuritypolicy.yaml @@ -0,0 +1,47 @@ +{{- if (and .Values.global.enablePodSecurityPolicies .Values.terminatingGateways.enabled) }} +{{- $root := . }} +{{- range .Values.terminatingGateways.gateways }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "consul.fullname" $root }}-{{ .name }} + namespace: {{ $root.Release.Namespace }} + labels: + app: {{ template "consul.name" $root }} + chart: {{ template "consul.chart" $root }} + heritage: {{ $root.Release.Service }} + release: {{ $root.Release.Name }} + component: terminating-gateway + terminating-gateway-name: {{ template "consul.fullname" $root }}-{{ .name }} +spec: + privileged: false + # Required to prevent escalations to root. + allowPrivilegeEscalation: false + # This is redundant with non-root + disallow privilege escalation, + # but we can provide it for defense in depth. + requiredDropCapabilities: + - ALL + defaultAddCapabilities: + - NET_BIND_SERVICE + # Allow core volume types. + volumes: + - 'configMap' + - 'emptyDir' + - 'projected' + - 'secret' + - 'downwardAPI' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' + readOnlyRootFilesystem: false +--- +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/terminating-gateways-role.yaml b/kubernetes-vault/consul/templates/terminating-gateways-role.yaml new file mode 100644 index 0000000..51e3766 --- /dev/null +++ b/kubernetes-vault/consul/templates/terminating-gateways-role.yaml @@ -0,0 +1,32 @@ +{{- if .Values.terminatingGateways.enabled }} + +{{- $root := . }} +{{- $defaults := .Values.terminatingGateways.defaults }} + +{{- range .Values.terminatingGateways.gateways }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "consul.fullname" $root }}-{{ .name }} + namespace: {{ $root.Release.Namespace }} + labels: + app: {{ template "consul.name" $root }} + chart: {{ template "consul.chart" $root }} + heritage: {{ $root.Release.Service }} + release: {{ $root.Release.Name }} + component: terminating-gateway + terminating-gateway-name: {{ template "consul.fullname" $root }}-{{ .name }} +{{- if $root.Values.global.enablePodSecurityPolicies }} +rules: + - apiGroups: ["policy"] + resources: ["podsecuritypolicies"] + resourceNames: + - {{ template "consul.fullname" $root }}-{{ .name }} + verbs: + - use +{{- else }} +rules: [] +{{- end }} +--- +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/terminating-gateways-rolebinding.yaml b/kubernetes-vault/consul/templates/terminating-gateways-rolebinding.yaml new file mode 100644 index 0000000..4271f8f --- /dev/null +++ b/kubernetes-vault/consul/templates/terminating-gateways-rolebinding.yaml @@ -0,0 +1,26 @@ +{{- if .Values.terminatingGateways.enabled }} +{{- $root := . }} +{{- range .Values.terminatingGateways.gateways }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "consul.fullname" $root }}-{{ .name }} + namespace: {{ $root.Release.Namespace }} + labels: + app: {{ template "consul.name" $root }} + chart: {{ template "consul.chart" $root }} + heritage: {{ $root.Release.Service }} + release: {{ $root.Release.Name }} + component: terminating-gateway + terminating-gateway-name: {{ template "consul.fullname" $root }}-{{ .name }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "consul.fullname" $root }}-{{ .name }} +subjects: + - kind: ServiceAccount + name: {{ template "consul.fullname" $root }}-{{ .name }} + namespace: {{ $root.Release.Namespace }} +--- +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/terminating-gateways-service.yaml b/kubernetes-vault/consul/templates/terminating-gateways-service.yaml new file mode 100644 index 0000000..124900e --- /dev/null +++ b/kubernetes-vault/consul/templates/terminating-gateways-service.yaml @@ -0,0 +1,31 @@ +{{- if .Values.terminatingGateways.enabled }} + +{{- $root := . }} +{{- $defaults := .Values.terminatingGateways.defaults }} + +{{- range .Values.terminatingGateways.gateways }} + +{{- $service := .service }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "consul.fullname" $root }}-{{ .name }} + namespace: {{ $root.Release.Namespace }} + labels: + app: {{ template "consul.name" $root }} + chart: {{ template "consul.chart" $root }} + heritage: {{ $root.Release.Service }} + release: {{ $root.Release.Name }} + component: terminating-gateway +spec: + selector: + app: {{ template "consul.name" $root }} + release: "{{ $root.Release.Name }}" + component: terminating-gateway + type: ClusterIP + ports: + - port: 80 + targetPort: 8443 +--- +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/terminating-gateways-serviceaccount.yaml b/kubernetes-vault/consul/templates/terminating-gateways-serviceaccount.yaml new file mode 100644 index 0000000..211fb5c --- /dev/null +++ b/kubernetes-vault/consul/templates/terminating-gateways-serviceaccount.yaml @@ -0,0 +1,35 @@ +{{- if .Values.terminatingGateways.enabled }} +{{- $root := . }} +{{- $defaults := .Values.terminatingGateways.defaults }} +{{- range .Values.terminatingGateways.gateways }} +{{- $serviceAccount := .serviceAccount }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "consul.fullname" $root }}-{{ .name }} + namespace: {{ $root.Release.Namespace }} + labels: + app: {{ template "consul.name" $root }} + chart: {{ template "consul.chart" $root }} + heritage: {{ $root.Release.Service }} + release: {{ $root.Release.Name }} + component: terminating-gateway + terminating-gateway-name: {{ template "consul.fullname" $root }}-{{ .name }} + {{- if (or $defaults.serviceAccount.annotations $serviceAccount.annotations) }} + annotations: + {{- if $defaults.serviceAccount.annotations }} + {{ tpl $defaults.serviceAccount.annotations $root | nindent 4 | trim }} + {{- end }} + {{- if $serviceAccount.annotations }} + {{ tpl $serviceAccount.annotations $root | nindent 4 | trim }} + {{- end }} + {{- end }} +{{- with $root.Values.global.imagePullSecrets }} +imagePullSecrets: +{{- range . }} + - name: {{ .name }} +{{- end }} +{{- end }} +--- +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/tests/test-runner.yaml b/kubernetes-vault/consul/templates/tests/test-runner.yaml new file mode 100644 index 0000000..4c3e81c --- /dev/null +++ b/kubernetes-vault/consul/templates/tests/test-runner.yaml @@ -0,0 +1,79 @@ +{{- if .Values.tests.enabled }} +apiVersion: v1 +kind: Pod +metadata: + name: "{{ template "consul.fullname" . }}-test" + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + annotations: + "helm.sh/hook": test-success +spec: + {{- if .Values.global.tls.enabled }} + volumes: + {{- if not (and .Values.externalServers.enabled .Values.externalServers.useSystemRoots) }} + - name: consul-ca-cert + secret: + {{- if .Values.global.tls.caCert.secretName }} + secretName: {{ .Values.global.tls.caCert.secretName }} + {{- else }} + secretName: {{ template "consul.fullname" . }}-ca-cert + {{- end }} + items: + - key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }} + path: tls.crt + {{- end }} + - name: consul-auto-encrypt-ca-cert + emptyDir: + medium: "Memory" + {{- end }} + {{- if and .Values.global.tls.enabled .Values.global.tls.enableAutoEncrypt }} + initContainers: + {{- include "consul.getAutoEncryptClientCA" . | nindent 2 }} + {{- end }} + containers: + - name: consul-test + image: "{{ .Values.global.image }}" + {{ template "consul.imagePullPolicy" . }} + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + {{- if .Values.global.tls.enabled }} + - name: CONSUL_HTTP_ADDR + value: https://$(HOST_IP):8501 + - name: CONSUL_CACERT + value: /consul/tls/ca/tls.crt + {{- else }} + - name: CONSUL_HTTP_ADDR + value: http://$(HOST_IP):8500 + {{- end }} + {{- if .Values.global.tls.enabled }} + volumeMounts: + {{- if .Values.global.tls.enableAutoEncrypt }} + - name: consul-auto-encrypt-ca-cert + mountPath: /consul/tls/ca + readOnly: true + {{- else }} + - name: consul-ca-cert + mountPath: /consul/tls/ca + readOnly: true + {{- end }} + {{- end }} + command: + - "/bin/sh" + - "-ec" + - | + consul members | tee members.txt + if [ $(grep -c consul-server members.txt) != $(grep consul-server members.txt | grep -c alive) ] + then + echo "Failed because not all consul servers are available" + exit 1 + fi + + restartPolicy: Never +{{- end }} diff --git a/kubernetes-vault/consul/templates/tls-init-cleanup-job.yaml b/kubernetes-vault/consul/templates/tls-init-cleanup-job.yaml new file mode 100644 index 0000000..5ebe236 --- /dev/null +++ b/kubernetes-vault/consul/templates/tls-init-cleanup-job.yaml @@ -0,0 +1,85 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if (and .Values.global.tls.enabled (not .Values.server.serverCert.secretName)) }} +{{- if not .Values.global.secretsBackend.vault.enabled }} +# tls-init-cleanup job deletes Kubernetes secrets created by tls-init +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ template "consul.fullname" . }}-tls-init-cleanup + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: tls-init-cleanup + {{- if .Values.global.extraLabels }} + {{- toYaml .Values.global.extraLabels | nindent 4 }} + {{- end }} + annotations: + "helm.sh/hook": pre-delete + "helm.sh/hook-delete-policy": hook-succeeded + {{- /* Hook weight needs to be 1 so that the service account is provisioned first */}} + "helm.sh/hook-weight": "1" +spec: + template: + metadata: + name: {{ template "consul.fullname" . }}-tls-init-cleanup + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: tls-init-cleanup + {{- if .Values.global.extraLabels }} + {{- toYaml .Values.global.extraLabels | nindent 8 }} + {{- end }} + annotations: + "consul.hashicorp.com/connect-inject": "false" + "consul.hashicorp.com/mesh-inject": "false" + {{- if .Values.global.tls.annotations }} + {{- tpl .Values.global.tls.annotations . | nindent 8 }} + {{- end }} + spec: + restartPolicy: Never + serviceAccountName: {{ template "consul.fullname" . }}-tls-init-cleanup + {{- if .Values.server.containerSecurityContext.tlsInit }} + securityContext: + {{- toYaml .Values.server.containerSecurityContext.tlsInit | nindent 8 }} + {{- end }} + containers: + - name: tls-init-cleanup + image: "{{ .Values.global.image }}" + {{ template "consul.imagePullPolicy" . }} + {{- if not .Values.server.containerSecurityContext.tlsInit }} + {{- include "consul.restrictedSecurityContext" . | nindent 10 }} + {{- end }} + env: + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + command: + - "/bin/sh" + - "-ec" + - | + {{- if (not (and .Values.global.tls.caCert.secretName .Values.global.tls.caKey.secretName)) }} + curl -s -X DELETE --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \ + https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT}/api/v1/namespaces/${NAMESPACE}/secrets/{{ template "consul.fullname" . }}-ca-cert \ + -H "Authorization: Bearer $( cat /var/run/secrets/kubernetes.io/serviceaccount/token )" + curl -s -X DELETE --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \ + https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT}/api/v1/namespaces/${NAMESPACE}/secrets/{{ template "consul.fullname" . }}-ca-key \ + -H "Authorization: Bearer $( cat /var/run/secrets/kubernetes.io/serviceaccount/token )" + {{- end }} + curl -s -X DELETE --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \ + https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT}/api/v1/namespaces/${NAMESPACE}/secrets/{{ template "consul.fullname" . }}-server-cert \ + -H "Authorization: Bearer $( cat /var/run/secrets/kubernetes.io/serviceaccount/token )" + resources: + requests: + memory: "50Mi" + cpu: "50m" + limits: + memory: "50Mi" + cpu: "50m" +{{- end }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/tls-init-cleanup-podsecuritypolicy.yaml b/kubernetes-vault/consul/templates/tls-init-cleanup-podsecuritypolicy.yaml new file mode 100644 index 0000000..ed99d5f --- /dev/null +++ b/kubernetes-vault/consul/templates/tls-init-cleanup-podsecuritypolicy.yaml @@ -0,0 +1,43 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if (and (and .Values.global.tls.enabled .Values.global.enablePodSecurityPolicies) (not .Values.server.serverCert.secretName)) }} +{{- if not .Values.global.secretsBackend.vault.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "consul.fullname" . }}-tls-init-cleanup + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: tls-init-cleanup + annotations: + "helm.sh/hook": pre-delete + "helm.sh/hook-delete-policy": hook-succeeded +spec: + privileged: false + # Required to prevent escalations to root. + allowPrivilegeEscalation: false + # This is redundant with non-root + disallow privilege escalation, + # but we can provide it for defense in depth. + requiredDropCapabilities: + - ALL + # Allow core volume types. + volumes: + - 'secret' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' + readOnlyRootFilesystem: false +{{- end }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/tls-init-cleanup-role.yaml b/kubernetes-vault/consul/templates/tls-init-cleanup-role.yaml new file mode 100644 index 0000000..aa66e3e --- /dev/null +++ b/kubernetes-vault/consul/templates/tls-init-cleanup-role.yaml @@ -0,0 +1,41 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if (and .Values.global.tls.enabled (not .Values.server.serverCert.secretName)) }} +{{- if not .Values.global.secretsBackend.vault.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "consul.fullname" . }}-tls-init-cleanup + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: tls-init-cleanup + annotations: + "helm.sh/hook": pre-delete + "helm.sh/hook-delete-policy": hook-succeeded +rules: +- apiGroups: [""] + resources: + - secrets + resourceNames: + {{- if (not (and .Values.global.tls.caCert.secretName .Values.global.tls.caKey.secretName)) }} + - {{ template "consul.fullname" . }}-ca-cert + - {{ template "consul.fullname" . }}-ca-key + {{- end }} + - {{ template "consul.fullname" . }}-server-cert + verbs: + - delete +{{- if .Values.global.enablePodSecurityPolicies }} +- apiGroups: ["policy"] + resources: + - podsecuritypolicies + verbs: + - use + resourceNames: + - {{ template "consul.fullname" . }}-tls-init-cleanup +{{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/tls-init-cleanup-rolebinding.yaml b/kubernetes-vault/consul/templates/tls-init-cleanup-rolebinding.yaml new file mode 100644 index 0000000..0d3bfe3 --- /dev/null +++ b/kubernetes-vault/consul/templates/tls-init-cleanup-rolebinding.yaml @@ -0,0 +1,27 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if (and .Values.global.tls.enabled (not .Values.server.serverCert.secretName)) }} +{{- if not .Values.global.secretsBackend.vault.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "consul.fullname" . }}-tls-init-cleanup + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: tls-init-cleanup + annotations: + "helm.sh/hook": pre-delete + "helm.sh/hook-delete-policy": hook-succeeded +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "consul.fullname" . }}-tls-init-cleanup +subjects: +- kind: ServiceAccount + name: {{ template "consul.fullname" . }}-tls-init-cleanup +{{- end }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/tls-init-cleanup-serviceaccount.yaml b/kubernetes-vault/consul/templates/tls-init-cleanup-serviceaccount.yaml new file mode 100644 index 0000000..57e40dd --- /dev/null +++ b/kubernetes-vault/consul/templates/tls-init-cleanup-serviceaccount.yaml @@ -0,0 +1,26 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if (and .Values.global.tls.enabled (not .Values.server.serverCert.secretName)) }} +{{- if not .Values.global.secretsBackend.vault.enabled }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "consul.fullname" . }}-tls-init-cleanup + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: tls-init-cleanup + annotations: + "helm.sh/hook": pre-delete + "helm.sh/hook-delete-policy": hook-succeeded +{{- with .Values.global.imagePullSecrets }} +imagePullSecrets: +{{- range . }} + - name: {{ .name }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/tls-init-job.yaml b/kubernetes-vault/consul/templates/tls-init-job.yaml new file mode 100644 index 0000000..177472c --- /dev/null +++ b/kubernetes-vault/consul/templates/tls-init-job.yaml @@ -0,0 +1,127 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if (and .Values.global.tls.enabled (not .Values.server.serverCert.secretName)) }} +{{- if not .Values.global.secretsBackend.vault.enabled }} +# tls-init job generate Consul cluster CA and certificates for the Consul servers +# and creates Kubernetes secrets for them. +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ template "consul.fullname" . }}-tls-init + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: tls-init + {{- if .Values.global.extraLabels }} + {{- toYaml .Values.global.extraLabels | nindent 4 }} + {{- end }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-weight": "1" + "helm.sh/hook-delete-policy": hook-succeeded,before-hook-creation +spec: + template: + metadata: + name: {{ template "consul.fullname" . }}-tls-init + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + release: {{ .Release.Name }} + component: tls-init + {{- if .Values.global.extraLabels }} + {{- toYaml .Values.global.extraLabels | nindent 8 }} + {{- end }} + annotations: + "consul.hashicorp.com/connect-inject": "false" + "consul.hashicorp.com/mesh-inject": "false" + {{- if .Values.global.tls.annotations }} + {{- tpl .Values.global.tls.annotations . | nindent 8 }} + {{- end }} + spec: + restartPolicy: Never + serviceAccountName: {{ template "consul.fullname" . }}-tls-init + {{- if .Values.server.containerSecurityContext.tlsInit }} + securityContext: + {{- toYaml .Values.server.containerSecurityContext.tlsInit | nindent 8 }} + {{- end }} + {{- if (and .Values.global.tls.caCert.secretName .Values.global.tls.caKey.secretName) }} + volumes: + - name: consul-ca-cert + secret: + secretName: {{ .Values.global.tls.caCert.secretName }} + items: + - key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }} + path: tls.crt + - name: consul-ca-key + secret: + secretName: {{ .Values.global.tls.caKey.secretName }} + items: + - key: {{ default "tls.key" .Values.global.tls.caKey.secretKey }} + path: tls.key + {{- end }} + containers: + - name: tls-init + image: "{{ .Values.global.imageK8S }}" + {{ template "consul.imagePullPolicy" . }} + {{- if not .Values.server.containerSecurityContext.tlsInit }} + {{- include "consul.restrictedSecurityContext" . | nindent 10 }} + {{- end }} + env: + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + workingDir: /tmp + command: + - "/bin/sh" + - "-ec" + - | + # Suppress globbing so we can interpolate the $NAMESPACE environment variable + # and use * at the start of the dns name when setting -additional-dnsname. + set -o noglob + exec consul-k8s-control-plane tls-init \ + -log-level={{ default .Values.global.logLevel .Values.global.tls.logLevel }} \ + -log-json={{ .Values.global.logJSON }} \ + -domain={{ .Values.global.domain }} \ + -days=730 \ + -name-prefix={{ template "consul.fullname" . }} \ + -k8s-namespace=${NAMESPACE} \ + {{- if (and .Values.global.tls.caCert.secretName .Values.global.tls.caKey.secretName) }} + -ca=/consul/tls/ca/cert/tls.crt \ + -key=/consul/tls/ca/key/tls.key \ + {{- end }} + -additional-dnsname="{{ template "consul.fullname" . }}-server" \ + -additional-dnsname="*.{{ template "consul.fullname" . }}-server" \ + -additional-dnsname="*.{{ template "consul.fullname" . }}-server.${NAMESPACE}" \ + -additional-dnsname="{{ template "consul.fullname" . }}-server.${NAMESPACE}" \ + -additional-dnsname="*.{{ template "consul.fullname" . }}-server.${NAMESPACE}.svc" \ + -additional-dnsname="{{ template "consul.fullname" . }}-server.${NAMESPACE}.svc" \ + -additional-dnsname="*.server.{{ .Values.global.datacenter }}.{{ .Values.global.domain }}" \ + {{- range .Values.global.tls.serverAdditionalIPSANs }} + -additional-ipaddress={{ . }} \ + {{- end }} + {{- range .Values.global.tls.serverAdditionalDNSSANs }} + -additional-dnsname={{ . }} \ + {{- end }} + -dc={{ .Values.global.datacenter }} + {{- if (and .Values.global.tls.caCert.secretName .Values.global.tls.caKey.secretName) }} + volumeMounts: + - name: consul-ca-cert + mountPath: /consul/tls/ca/cert + readOnly: true + - name: consul-ca-key + mountPath: /consul/tls/ca/key + readOnly: true + {{- end }} + resources: + requests: + memory: "50Mi" + cpu: "50m" + limits: + memory: "50Mi" + cpu: "50m" +{{- end }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/tls-init-podsecuritypolicy.yaml b/kubernetes-vault/consul/templates/tls-init-podsecuritypolicy.yaml new file mode 100644 index 0000000..5d2a393 --- /dev/null +++ b/kubernetes-vault/consul/templates/tls-init-podsecuritypolicy.yaml @@ -0,0 +1,43 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if (and (and .Values.global.tls.enabled .Values.global.enablePodSecurityPolicies) (not .Values.server.serverCert.secretName)) }} +{{- if not .Values.global.secretsBackend.vault.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "consul.fullname" . }}-tls-init + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: tls-init + annotations: + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-delete-policy": before-hook-creation +spec: + privileged: false + # Required to prevent escalations to root. + allowPrivilegeEscalation: false + # This is redundant with non-root + disallow privilege escalation, + # but we can provide it for defense in depth. + requiredDropCapabilities: + - ALL + # Allow core volume types. + volumes: + - 'secret' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' + readOnlyRootFilesystem: false +{{- end }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/tls-init-role.yaml b/kubernetes-vault/consul/templates/tls-init-role.yaml new file mode 100644 index 0000000..216602e --- /dev/null +++ b/kubernetes-vault/consul/templates/tls-init-role.yaml @@ -0,0 +1,38 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if (and .Values.global.tls.enabled (not .Values.server.serverCert.secretName)) }} +{{- if not .Values.global.secretsBackend.vault.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "consul.fullname" . }}-tls-init + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: tls-init + annotations: + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-delete-policy": before-hook-creation +rules: +- apiGroups: [""] + resources: + - secrets + verbs: + - create + - update + - get + - list +{{- if .Values.global.enablePodSecurityPolicies }} +- apiGroups: ["policy"] + resources: + - podsecuritypolicies + verbs: + - use + resourceNames: + - {{ template "consul.fullname" . }}-tls-init +{{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/tls-init-rolebinding.yaml b/kubernetes-vault/consul/templates/tls-init-rolebinding.yaml new file mode 100644 index 0000000..9b68d97 --- /dev/null +++ b/kubernetes-vault/consul/templates/tls-init-rolebinding.yaml @@ -0,0 +1,27 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if (and .Values.global.tls.enabled (not .Values.server.serverCert.secretName)) }} +{{- if not .Values.global.secretsBackend.vault.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "consul.fullname" . }}-tls-init + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: tls-init + annotations: + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-delete-policy": before-hook-creation +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "consul.fullname" . }}-tls-init +subjects: +- kind: ServiceAccount + name: {{ template "consul.fullname" . }}-tls-init +{{- end }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/tls-init-serviceaccount.yaml b/kubernetes-vault/consul/templates/tls-init-serviceaccount.yaml new file mode 100644 index 0000000..f8504da --- /dev/null +++ b/kubernetes-vault/consul/templates/tls-init-serviceaccount.yaml @@ -0,0 +1,26 @@ +{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} +{{- if (and .Values.global.tls.enabled (not .Values.server.serverCert.secretName)) }} +{{- if not .Values.global.secretsBackend.vault.enabled }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "consul.fullname" . }}-tls-init + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: tls-init + annotations: + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-delete-policy": before-hook-creation +{{- with .Values.global.imagePullSecrets }} +imagePullSecrets: +{{- range . }} + - name: {{ .name }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/ui-ingress.yaml b/kubernetes-vault/consul/templates/ui-ingress.yaml new file mode 100644 index 0000000..f8c7f92 --- /dev/null +++ b/kubernetes-vault/consul/templates/ui-ingress.yaml @@ -0,0 +1,85 @@ +{{- if (and (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) (or (and (ne (.Values.ui.enabled | toString) "-") .Values.ui.enabled) (and (eq (.Values.ui.enabled | toString) "-") .Values.global.enabled)) (or (and (ne (.Values.ui.service.enabled | toString) "-") .Values.ui.service.enabled) (and (eq (.Values.ui.service.enabled | toString) "-") .Values.global.enabled))) }} +{{- if (and (ne (.Values.ui.ingress.enabled | toString) "-") .Values.ui.ingress.enabled) }} +{{- $serviceName := printf "%s-%s" (include "consul.fullname" .) "ui" -}} +{{- /* We use the kube version to determine if the apiVersion of networking.k8s.io should be v1 or v1beta1. +This is because while networks.k8s.io/v1 was introduced in Kubernetes v1.15+, the Ingress resource was +promoted to v1 only in Kubernetes v1.19+. This ensures the correct API version is chosen that supports +the Ingress resource. */}} +{{- if or ( gt .Capabilities.KubeVersion.Major "1" ) ( ge .Capabilities.KubeVersion.Minor "19" ) }} +apiVersion: networking.k8s.io/v1 +{{- else }} +apiVersion: networking.k8s.io/v1beta1 +{{- end }} +kind: Ingress +metadata: + name: {{ template "consul.fullname" . }}-ui + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: ui + {{- if .Values.ui.ingress.annotations }} + annotations: + {{ tpl .Values.ui.ingress.annotations . | nindent 4 | trim }} + {{- end }} +spec: + {{- if ne .Values.ui.ingress.ingressClassName "" }} + ingressClassName: {{ .Values.ui.ingress.ingressClassName }} + {{- end }} + rules: + {{- $global := .Values.global }} + {{- if or ( gt .Capabilities.KubeVersion.Major "1" ) ( ge .Capabilities.KubeVersion.Minor "19" ) }} + {{- range .Values.ui.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range (.paths | default (list "/")) }} + {{- if (or (not $global.tls.enabled) (not $global.tls.httpsOnly)) }} + - backend: + service: + name: {{ $serviceName }} + port: + number: 80 + path: {{ . }} + pathType: {{ $.Values.ui.ingress.pathType }} + {{- end }} + {{- if $global.tls.enabled }} + - backend: + service: + name: {{ $serviceName }} + port: + number: 443 + path: {{ . }} + pathType: {{ $.Values.ui.ingress.pathType }} + {{- end }} + {{- end }} + {{- end }} + {{- else }} + {{- range .Values.ui.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range (.paths | default (list "/")) }} + {{- if (or (not $global.tls.enabled) (not $global.tls.httpsOnly)) }} + - backend: + serviceName: {{ $serviceName }} + servicePort: 80 + path: {{ . }} + {{- end }} + {{- if $global.tls.enabled }} + - backend: + serviceName: {{ $serviceName }} + servicePort: 443 + path: {{ . }} + {{- end }} + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.ui.ingress.tls }} + tls: + {{- toYaml .Values.ui.ingress.tls | nindent 4 }} + {{- end }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/ui-service.yaml b/kubernetes-vault/consul/templates/ui-service.yaml new file mode 100644 index 0000000..dc2abf4 --- /dev/null +++ b/kubernetes-vault/consul/templates/ui-service.yaml @@ -0,0 +1,46 @@ +{{- if (and (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) (or (and (ne (.Values.ui.enabled | toString) "-") .Values.ui.enabled) (and (eq (.Values.ui.enabled | toString) "-") .Values.global.enabled)) (or (and (ne (.Values.ui.service.enabled | toString) "-") .Values.ui.service.enabled) (and (eq (.Values.ui.service.enabled | toString) "-") .Values.global.enabled))) }} +# UI Service for Consul Server +apiVersion: v1 +kind: Service +metadata: + name: {{ template "consul.fullname" . }}-ui + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: ui + {{- if .Values.ui.service.annotations }} + annotations: + {{ tpl .Values.ui.service.annotations . | nindent 4 | trim }} + {{- end }} +spec: + selector: + app: {{ template "consul.name" . }} + release: "{{ .Release.Name }}" + component: server + ports: + {{- if (or (not .Values.global.tls.enabled) (not .Values.global.tls.httpsOnly)) }} + - name: http + port: {{ .Values.ui.service.port.http }} + targetPort: 8500 + {{- if .Values.ui.service.type }}{{ if (and (eq .Values.ui.service.type "NodePort") .Values.ui.service.nodePort.http) }} + nodePort: {{ .Values.ui.service.nodePort.http }} + {{- end }}{{ end }} + {{- end }} + {{- if .Values.global.tls.enabled }} + - name: https + port: {{ .Values.ui.service.port.https }} + targetPort: 8501 + {{- if .Values.ui.service.type }}{{ if (and (eq .Values.ui.service.type "NodePort") .Values.ui.service.nodePort.https) }} + nodePort: {{ .Values.ui.service.nodePort.https }} + {{- end }}{{ end }} + {{- end }} + {{- if .Values.ui.service.type }} + type: {{ .Values.ui.service.type }} + {{- end }} + {{- if .Values.ui.service.additionalSpec }} + {{ tpl .Values.ui.service.additionalSpec . | nindent 2 | trim }} + {{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/webhook-cert-manager-clusterrole.yaml b/kubernetes-vault/consul/templates/webhook-cert-manager-clusterrole.yaml new file mode 100644 index 0000000..2a5c80d --- /dev/null +++ b/kubernetes-vault/consul/templates/webhook-cert-manager-clusterrole.yaml @@ -0,0 +1,54 @@ +{{ $hasConfiguredWebhookCertsUsingVault := (and .Values.global.secretsBackend.vault.enabled .Values.global.secretsBackend.vault.connectInjectRole .Values.global.secretsBackend.vault.connectInject.tlsCert.secretName .Values.global.secretsBackend.vault.connectInject.caCert.secretName) -}} +{{- if (and .Values.connectInject.enabled (not $hasConfiguredWebhookCertsUsingVault)) }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "consul.fullname" . }}-webhook-cert-manager + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: webhook-cert-manager +rules: +- apiGroups: + - "" + resources: + - secrets + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - admissionregistration.k8s.io + resources: + - mutatingwebhookconfigurations + - validatingwebhookconfigurations + verbs: + - get + - list + - watch + - patch +- apiGroups: + - apps + resources: + - deployments + resourceNames: + - {{ template "consul.fullname" . }}-webhook-cert-manager + verbs: + - get +{{- if .Values.global.enablePodSecurityPolicies }} +- apiGroups: + - policy + resources: + - podsecuritypolicies + resourceNames: + - {{ template "consul.fullname" . }}-webhook-cert-manager + verbs: + - use +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/webhook-cert-manager-clusterrolebinding.yaml b/kubernetes-vault/consul/templates/webhook-cert-manager-clusterrolebinding.yaml new file mode 100644 index 0000000..472ef4e --- /dev/null +++ b/kubernetes-vault/consul/templates/webhook-cert-manager-clusterrolebinding.yaml @@ -0,0 +1,21 @@ +{{ $hasConfiguredWebhookCertsUsingVault := (and .Values.global.secretsBackend.vault.enabled .Values.global.secretsBackend.vault.connectInjectRole .Values.global.secretsBackend.vault.connectInject.tlsCert.secretName .Values.global.secretsBackend.vault.connectInject.caCert.secretName) -}} +{{- if (and .Values.connectInject.enabled (not $hasConfiguredWebhookCertsUsingVault)) }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "consul.fullname" . }}-webhook-cert-manager + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: webhook-cert-manager +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "consul.fullname" . }}-webhook-cert-manager +subjects: +- kind: ServiceAccount + name: {{ template "consul.fullname" . }}-webhook-cert-manager + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/webhook-cert-manager-configmap.yaml b/kubernetes-vault/consul/templates/webhook-cert-manager-configmap.yaml new file mode 100644 index 0000000..293dd32 --- /dev/null +++ b/kubernetes-vault/consul/templates/webhook-cert-manager-configmap.yaml @@ -0,0 +1,29 @@ +{{ $hasConfiguredWebhookCertsUsingVault := (and .Values.global.secretsBackend.vault.enabled .Values.global.secretsBackend.vault.connectInjectRole .Values.global.secretsBackend.vault.connectInject.tlsCert.secretName .Values.global.secretsBackend.vault.connectInject.caCert.secretName) -}} +{{- if (and .Values.connectInject.enabled (not $hasConfiguredWebhookCertsUsingVault)) }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "consul.fullname" . }}-webhook-cert-manager-config + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: webhook-cert-manager +data: + webhook-config.json: |- + [ + { + "name": "{{ template "consul.fullname" . }}-connect-injector", + "tlsAutoHosts": [ + "{{ template "consul.fullname" . }}-connect-injector", + "{{ template "consul.fullname" . }}-connect-injector.{{ .Release.Namespace }}", + "{{ template "consul.fullname" . }}-connect-injector.{{ .Release.Namespace }}.svc", + "{{ template "consul.fullname" . }}-connect-injector.{{ .Release.Namespace }}.svc.cluster.local" + ], + "secretName": "{{ template "consul.fullname" . }}-connect-inject-webhook-cert", + "secretNamespace": "{{ .Release.Namespace }}" + } + ] + {{- end }} diff --git a/kubernetes-vault/consul/templates/webhook-cert-manager-deployment.yaml b/kubernetes-vault/consul/templates/webhook-cert-manager-deployment.yaml new file mode 100644 index 0000000..71cddca --- /dev/null +++ b/kubernetes-vault/consul/templates/webhook-cert-manager-deployment.yaml @@ -0,0 +1,79 @@ +{{ $hasConfiguredWebhookCertsUsingVault := (and .Values.global.secretsBackend.vault.enabled .Values.global.secretsBackend.vault.connectInjectRole .Values.global.secretsBackend.vault.connectInject.tlsCert.secretName .Values.global.secretsBackend.vault.connectInject.caCert.secretName) -}} +{{- if (and .Values.connectInject.enabled (not $hasConfiguredWebhookCertsUsingVault)) }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "consul.fullname" . }}-webhook-cert-manager + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: webhook-cert-manager + {{- if .Values.global.extraLabels }} + {{- toYaml .Values.global.extraLabels | nindent 4 }} + {{- end }} +spec: + replicas: 1 + selector: + matchLabels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: webhook-cert-manager + template: + metadata: + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: webhook-cert-manager + {{- if .Values.global.extraLabels }} + {{- toYaml .Values.global.extraLabels | nindent 8 }} + {{- end }} + annotations: + "consul.hashicorp.com/connect-inject": "false" + "consul.hashicorp.com/mesh-inject": "false" + "consul.hashicorp.com/config-checksum": {{ include (print $.Template.BasePath "/webhook-cert-manager-configmap.yaml") . | sha256sum }} + spec: + containers: + - command: + - "/bin/sh" + - "-ec" + - | + exec consul-k8s-control-plane webhook-cert-manager \ + -log-level={{ .Values.global.logLevel }} \ + -log-json={{ .Values.global.logJSON }} \ + -config-file=/bootstrap/config/webhook-config.json \ + -deployment-name={{ template "consul.fullname" . }}-webhook-cert-manager \ + -deployment-namespace={{ .Release.Namespace }} + image: {{ .Values.global.imageK8S }} + {{ template "consul.imagePullPolicy" . }} + name: webhook-cert-manager + {{- include "consul.restrictedSecurityContext" . | nindent 8 }} + {{- with .Values.webhookCertManager.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + - name: config + mountPath: /bootstrap/config + terminationGracePeriodSeconds: 10 + serviceAccountName: {{ template "consul.fullname" . }}-webhook-cert-manager + volumes: + - name: config + configMap: + name: {{ template "consul.fullname" . }}-webhook-cert-manager-config + {{- if .Values.webhookCertManager.tolerations }} + tolerations: + {{ tpl .Values.webhookCertManager.tolerations . | indent 8 | trim }} + {{- end }} + {{- if .Values.webhookCertManager.nodeSelector }} + nodeSelector: + {{ tpl .Values.webhookCertManager.nodeSelector . | indent 8 | trim }} + {{- end }} + +{{- end }} diff --git a/kubernetes-vault/consul/templates/webhook-cert-manager-podsecuritypolicy.yaml b/kubernetes-vault/consul/templates/webhook-cert-manager-podsecuritypolicy.yaml new file mode 100644 index 0000000..4d685ed --- /dev/null +++ b/kubernetes-vault/consul/templates/webhook-cert-manager-podsecuritypolicy.yaml @@ -0,0 +1,43 @@ +{{ $hasConfiguredWebhookCertsUsingVault := (and .Values.global.secretsBackend.vault.enabled .Values.global.secretsBackend.vault.connectInjectRole .Values.global.secretsBackend.vault.connectInject.tlsCert.secretName .Values.global.secretsBackend.vault.connectInject.caCert.secretName) -}} +{{- if (and .Values.global.enablePodSecurityPolicies (or (and (ne (.Values.connectInject.enabled | toString) "-") .Values.connectInject.enabled) (and (eq (.Values.connectInject.enabled | toString) "-") .Values.global.enabled))) }} +{{- if (and .Values.connectInject.enabled (not $hasConfiguredWebhookCertsUsingVault)) }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "consul.fullname" . }}-webhook-cert-manager + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: webhook-cert-manager +spec: + privileged: false + # Required to prevent escalations to root. + allowPrivilegeEscalation: false + # This is redundant with non-root + disallow privilege escalation, + # but we can provide it for defense in depth. + requiredDropCapabilities: + - ALL + # Allow core volume types. + volumes: + - 'configMap' + - 'emptyDir' + - 'projected' + - 'secret' + - 'downwardAPI' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' + readOnlyRootFilesystem: false +{{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/templates/webhook-cert-manager-serviceaccount.yaml b/kubernetes-vault/consul/templates/webhook-cert-manager-serviceaccount.yaml new file mode 100644 index 0000000..68c54f3 --- /dev/null +++ b/kubernetes-vault/consul/templates/webhook-cert-manager-serviceaccount.yaml @@ -0,0 +1,20 @@ +{{ $hasConfiguredWebhookCertsUsingVault := (and .Values.global.secretsBackend.vault.enabled .Values.global.secretsBackend.vault.connectInjectRole .Values.global.secretsBackend.vault.connectInject.tlsCert.secretName .Values.global.secretsBackend.vault.connectInject.caCert.secretName) -}} +{{- if (and .Values.connectInject.enabled (not $hasConfiguredWebhookCertsUsingVault)) }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "consul.fullname" . }}-webhook-cert-manager + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "consul.name" . }} + chart: {{ template "consul.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + component: webhook-cert-manager + {{- with .Values.global.imagePullSecrets }} +imagePullSecrets: + {{- range . }} +- name: {{ .name }} + {{- end }} + {{- end }} +{{- end }} diff --git a/kubernetes-vault/consul/values.yaml b/kubernetes-vault/consul/values.yaml new file mode 100644 index 0000000..1bcc440 --- /dev/null +++ b/kubernetes-vault/consul/values.yaml @@ -0,0 +1,3669 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +# Available parameters and their default values for the Consul chart. + +# Holds values that affect multiple components of the chart. +global: + # The main enabled/disabled setting. If true, servers, + # clients, Consul DNS and the Consul UI will be enabled. Each component can override + # this default via its component-specific "enabled" config. If false, no components + # will be installed by default and per-component opt-in is required, such as by + # setting `server.enabled` to true. + enabled: true + + # The default log level to apply to all components which do not otherwise override this setting. + # It is recommended to generally not set this below "info" unless actively debugging due to logging verbosity. + # One of "debug", "info", "warn", or "error". + # @type: string + logLevel: "info" + + # Enable all component logs to be output in JSON format. + # @type: boolean + logJSON: false + + # Set the prefix used for all resources in the Helm chart. If not set, + # the prefix will be `-consul`. + # @type: string + name: null + + # The domain Consul will answer DNS queries for + # (Refer to [`-domain`](https://developer.hashicorp.com/consul/docs/agent/config/cli-flags#_domain)) and the domain services synced from + # Consul into Kubernetes will have, e.g. `service-name.service.consul`. + domain: consul + + # Configures the Cluster Peering feature. Requires Consul v1.14+ and Consul-K8s v1.0.0+. + peering: + # If true, the Helm chart enables Cluster Peering for the cluster. This option enables peering controllers and + # allows use of the PeeringAcceptor and PeeringDialer CRDs for establishing service mesh peerings. + enabled: false + + # [Enterprise Only] Enabling `adminPartitions` allows creation of Admin Partitions in Kubernetes clusters. + # It additionally indicates that you are running Consul Enterprise v1.11+ with a valid Consul Enterprise + # license. Admin partitions enables deploying services across partitions, while sharing + # a set of Consul servers. + adminPartitions: + # If true, the Helm chart will enable Admin Partitions for the cluster. The clients in the server cluster + # must be installed in the default partition. Creation of Admin Partitions is only supported during installation. + # Admin Partitions cannot be installed via a Helm upgrade operation. Only Helm installs are supported. + enabled: false + + # The name of the Admin Partition. The partition name cannot be modified once the partition has been installed. + # Changing the partition name would require an un-install and a re-install with the updated name. + # Must be "default" in the server cluster ie the Kubernetes cluster that the Consul server pods are deployed onto. + name: "default" + + # The name (and tag) of the Consul Docker image for clients and servers. + # This can be overridden per component. This should be pinned to a specific + # version tag, otherwise you may inadvertently upgrade your Consul version. + # + # Examples: + # + # ```yaml + # # Consul 1.10.0 + # image: "consul:1.10.0" + # # Consul Enterprise 1.10.0 + # image: "hashicorp/consul-enterprise:1.10.0-ent" + # ``` + # @default: hashicorp/consul: + image: hashicorp/consul:1.19.2 + + # Array of objects containing image pull secret names that will be applied to each service account. + # This can be used to reference image pull secrets if using a custom consul or consul-k8s-control-plane Docker image. + # Refer to https://kubernetes.io/docs/concepts/containers/images/#using-a-private-registry. + # + # Example: + # + # ```yaml + # imagePullSecrets: + # - name: pull-secret-name + # - name: pull-secret-name-2 + # ``` + # @type: array + imagePullSecrets: [] + + # The name (and tag) of the consul-k8s-control-plane Docker + # image that is used for functionality such as catalog sync. + # This can be overridden per component. + # @default: hashicorp/consul-k8s-control-plane: + imageK8S: hashicorp/consul-k8s-control-plane:1.5.3 + + # The image pull policy used globally for images controlled by Consul (consul, consul-dataplane, consul-k8s, consul-telemetry-collector). + # One of "IfNotPresent", "Always", "Never", and "". Refer to https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy + # @default: "" + imagePullPolicy: "" + + # The name of the datacenter that the agents should + # register as. This can't be changed once the Consul cluster is up and running + # since Consul doesn't support an automatic way to change this value currently: + # https://github.com/hashicorp/consul/issues/1858. + datacenter: dc1 + + # Controls whether pod security policies are created for the Consul components + # created by this chart. Refer to https://kubernetes.io/docs/concepts/policy/pod-security-policy/. + enablePodSecurityPolicies: false + + # secretsBackend is used to configure Vault as the secrets backend for the Consul on Kubernetes installation. + # The Vault cluster needs to have the Kubernetes Auth Method, KV2 and PKI secrets engines enabled + # and have necessary secrets, policies and roles created prior to installing Consul. + # Refer to [Vault as the Secrets Backend](https://developer.hashicorp.com/consul/docs/k8s/deployment-configurations/vault) + # documentation for full instructions. + # + # The Vault cluster _must_ not have the Consul cluster installed by this Helm chart as its storage backend + # as that would cause a circular dependency. + # Vault can have Consul as its storage backend as long as that Consul cluster is not running on this Kubernetes cluster + # and is being managed separately from this Helm installation. + # + # Note: When using Vault KV2 secrets engines the "data" field is implicitly required for Vault API calls, + # secretName should be in the form of "vault-kv2-mount-path/data/secret-name". + # secretKey should be in the form of "key". + secretsBackend: + vault: + # Vault namespace (optional). This sets the Vault namespace for the `vault.hashicorp.com/namespace` + # agent annotation and [Vault Connect CA namespace](https://developer.hashicorp.com/consul/docs/connect/ca/vault#namespace). + # To override one of these values individually, see `agentAnnotations` and `connectCA.additionalConfig`. + vaultNamespace: "" + + # Enabling the Vault secrets backend will replace Kubernetes secrets with referenced Vault secrets. + enabled: false + + # The Vault role for the Consul server. + # The role must be connected to the Consul server's service account. + # The role must also have a policy with read capabilities for the following secrets: + # - gossip encryption key defined by the `global.gossipEncryption.secretName` value + # - certificate issue path defined by the `server.serverCert.secretName` value + # - CA certificate defined by the `global.tls.caCert.secretName` value + # - replication token defined by the `global.acls.replicationToken.secretName` value if `global.federation.enabled` is `true` + # To discover the service account name of the Consul server, run + # ```shell-session + # $ helm template --show-only templates/server-serviceaccount.yaml hashicorp/consul + # ``` + # and check the name of `metadata.name`. + consulServerRole: "" + + # The Vault role for the Consul client. + # The role must be connected to the Consul client's service account. + # The role must also have a policy with read capabilities for the gossip encryption + # key defined by the `global.gossipEncryption.secretName` value. + # To discover the service account name of the Consul client, run + # ```shell-session + # $ helm template --show-only templates/client-serviceaccount.yaml hashicorp/consul + # ``` + # and check the name of `metadata.name`. + consulClientRole: "" + + # A Vault role for the Consul `server-acl-init` job, which manages setting ACLs so that clients and components can obtain ACL tokens. + # The role must be connected to the `server-acl-init` job's service account. + # The role must also have a policy with read and write capabilities for the bootstrap, replication or partition tokens + # To discover the service account name of the `server-acl-init` job, run + # ```shell-session + # $ helm template --show-only templates/server-acl-init-serviceaccount.yaml \ + # --set global.acls.manageSystemACLs=true hashicorp/consul + # ``` + # and check the name of `metadata.name`. + manageSystemACLsRole: "" + + # [Enterprise Only] A Vault role that allows the Consul `partition-init` job to read a Vault secret for the partition ACL token. + # The `partition-init` job bootstraps Admin Partitions on Consul servers. + # . + # This role must be bound the `partition-init` job's service account. + # To discover the service account name of the `partition-init` job, run with Helm values for the client cluster: + # ```shell-session + # $ helm template --show-only templates/partition-init-serviceaccount.yaml -f client-cluster-values.yaml hashicorp/consul + # ``` + # and check the name of `metadata.name`. + adminPartitionsRole: "" + + # The Vault role to read Consul connect-injector webhook's CA + # and issue a certificate and private key. + # A Vault policy must be created which grants issue capabilities to + # `global.secretsBackend.vault.connectInject.tlsCert.secretName`. + connectInjectRole: "" + + # The Vault role for all Consul components to read the Consul's server's CA Certificate (unauthenticated). + # The role should be connected to the service accounts of all Consul components, or alternatively `*` since it + # will be used only against the `pki/cert/ca` endpoint which is unauthenticated. A policy must be created which grants + # read capabilities to `global.tls.caCert.secretName`, which is usually `pki/cert/ca`. + consulCARole: "" + + # This value defines additional annotations for + # Vault agent on any pods where it'll be running. + # This should be formatted as a multi-line string. + # + # ```yaml + # annotations: | + # "sample/annotation1": "foo" + # "sample/annotation2": "bar" + # ``` + # + # @type: string + agentAnnotations: null + + # Configuration for Vault server CA certificate. This certificate will be mounted + # to any pod where Vault agent needs to run. + ca: + # The name of the Kubernetes or Vault secret that holds the Vault CA certificate. + # A Kubernetes secret must be in the same namespace that Consul is installed into. + secretName: "" + # The key within the Kubernetes or Vault secret that holds the Vault CA certificate. + secretKey: "" + + # Configuration for the Vault Connect CA provider. + # The provider will be configured to use the Vault Kubernetes auth method + # and therefore requires the role provided by `global.secretsBackend.vault.consulServerRole` + # to have permissions to the root and intermediate PKI paths. + # Please refer to [Vault ACL policies](https://developer.hashicorp.com/consul/docs/connect/ca/vault#vault-acl-policies) + # documentation for information on how to configure the Vault policies. + connectCA: + # The address of the Vault server. + address: "" + + # The mount path of the Kubernetes auth method in Vault. + authMethodPath: "kubernetes" + + # The path to a PKI secrets engine for the root certificate. + # For more details, please refer to [Vault Connect CA configuration](https://developer.hashicorp.com/consul/docs/connect/ca/vault#rootpkipath). + rootPKIPath: "" + + # The path to a PKI secrets engine for the generated intermediate certificate. + # For more details, please refer to [Vault Connect CA configuration](https://developer.hashicorp.com/consul/docs/connect/ca/vault#intermediatepkipath). + intermediatePKIPath: "" + + # Additional Connect CA configuration in JSON format. + # Please refer to [Vault Connect CA configuration](https://developer.hashicorp.com/consul/docs/connect/ca/vault#configuration) + # for all configuration options available for that provider. + # + # Example: + # + # ```yaml + # additionalConfig: | + # { + # "connect": [{ + # "ca_config": [{ + # "leaf_cert_ttl": "36h" + # }] + # }] + # } + # ``` + additionalConfig: | + {} + + connectInject: + # Configuration to the Vault Secret that Kubernetes uses on + # Kubernetes pod creation, deletion, and update, to get CA certificates + # used issued from vault to send webhooks to the ConnectInject. + caCert: + # The Vault secret path that contains the CA certificate for + # Connect Inject webhooks. + # @type: string + secretName: null + + # Configuration to the Vault Secret that Kubernetes uses on + # Kubernetes pod creation, deletion, and update, to get TLS certificates + # used issued from vault to send webhooks to the ConnectInject. + tlsCert: + # The Vault secret path that issues TLS certificates for connect + # inject webhooks. + # @type: string + secretName: null + + # Configures Consul's gossip encryption key. + # (Refer to [`-encrypt`](https://developer.hashicorp.com/consul/docs/agent/config/cli-flags#_encrypt)). + # By default, gossip encryption is not enabled. The gossip encryption key may be set automatically or manually. + # The recommended method is to automatically generate the key. + # To automatically generate and set a gossip encryption key, set autoGenerate to true. + # Values for secretName and secretKey should not be set if autoGenerate is true. + # To manually generate a gossip encryption key, set secretName and secretKey and use Consul to generate + # a key, saving this as a Kubernetes secret or Vault secret path and key. + # If `global.secretsBackend.vault.enabled=true`, be sure to add the "data" component of the secretName path as required by + # the Vault KV-2 secrets engine [refer to example]. + # + # ```shell-session + # $ kubectl create secret generic consul-gossip-encryption-key --from-literal=key=$(consul keygen) + # ``` + # + # Vault CLI Example: + # ```shell-session + # $ vault kv put consul/secrets/gossip key=$(consul keygen) + # ``` + # `gossipEncryption.secretName="consul/data/secrets/gossip"` + # `gossipEncryption.secretKey="key"` + + gossipEncryption: + # Automatically generate a gossip encryption key and save it to a Kubernetes or Vault secret. + autoGenerate: false + # The name of the Kubernetes secret or Vault secret path that holds the gossip + # encryption key. A Kubernetes secret must be in the same namespace that Consul is installed into. + secretName: "" + # The key within the Kubernetes secret or Vault secret key that holds the gossip + # encryption key. + secretKey: "" + # Override global log verbosity level for gossip-encryption-autogenerate-job pods. One of "trace", "debug", "info", "warn", or "error". + # @type: string + logLevel: "" + + # A list of addresses of upstream DNS servers that are used to recursively resolve DNS queries. + # These values are given as `-recursor` flags to Consul servers and clients. + # Refer to [`-recursor`](https://developer.hashicorp.com/consul/docs/agent/config/cli-flags#_recursor) for more details. + # If this is an empty array (the default), then Consul DNS will only resolve queries for the Consul top level domain (by default `.consul`). + # @type: array + recursors: [] + + # Enables [TLS](https://developer.hashicorp.com/consul/tutorials/security/tls-encryption-secure) + # across the cluster to verify authenticity of the Consul servers and clients. + # Requires Consul v1.4.1+. + tls: + # If true, the Helm chart will enable TLS for Consul + # servers and clients and all consul-k8s-control-plane components, as well as generate certificate + # authority (optional) and server and client certificates. + # This setting is required for [Cluster Peering](https://developer.hashicorp.com/consul/docs/connect/cluster-peering/k8s). + enabled: false + + # Override global log verbosity level. One of "trace", "debug", "info", "warn", or "error". + # @type: string + logLevel: "" + + # If true, turns on the auto-encrypt feature on clients and servers. + # It also switches consul-k8s-control-plane components to retrieve the CA from the servers + # via the API. Requires Consul 1.7.1+. + enableAutoEncrypt: false + + # A list of additional DNS names to set as Subject Alternative Names (SANs) + # in the server certificate. This is useful when you need to access the + # Consul server(s) externally, for example, if you're using the UI. + # @type: array + serverAdditionalDNSSANs: [] + + # A list of additional IP addresses to set as Subject Alternative Names (SANs) + # in the server certificate. This is useful when you need to access the + # Consul server(s) externally, for example, if you're using the UI. + # @type: array + serverAdditionalIPSANs: [] + + # If true, `verify_outgoing`, `verify_server_hostname`, + # and `verify_incoming` for internal RPC communication will be set to `true` for Consul servers and clients. + # Set this to false to incrementally roll out TLS on an existing Consul cluster. + # Please refer to [TLS on existing clusters](https://developer.hashicorp.com/consul/docs/k8s/operations/tls-on-existing-cluster) + # for more details. + verify: true + + # If true, the Helm chart will configure Consul to disable the HTTP port on + # both clients and servers and to only accept HTTPS connections. + httpsOnly: true + + # A secret containing the certificate of the CA to use for TLS communication within the Consul cluster. + # If you have generated the CA yourself with the consul CLI, you could use the following command to create the secret + # in Kubernetes: + # + # ```shell-session + # $ kubectl create secret generic consul-ca-cert \ + # --from-file='tls.crt=./consul-agent-ca.pem' + # ``` + # If you are using Vault as a secrets backend with TLS, `caCert.secretName` must be provided and should reference + # the CA path for your PKI secrets engine. This should be of the form `pki/cert/ca` where `pki` is the mount point of your PKI secrets engine. + # A read policy must be created and associated with the CA cert path for `global.tls.caCert.secretName`. + # This will be consumed by the `global.secretsBackend.vault.consulCARole` role by all Consul components. + # When using Vault the secretKey is not used. + caCert: + # The name of the Kubernetes or Vault secret that holds the CA certificate. + # @type: string + secretName: null + # The key within the Kubernetes or Vault secret that holds the CA certificate. + # @type: string + secretKey: null + + # A Kubernetes or Vault secret containing the private key of the CA to use for + # TLS communication within the Consul cluster. If you have generated the CA yourself + # with the consul CLI, you could use the following command to create the secret + # in Kubernetes: + # + # ```shell-session + # $ kubectl create secret generic consul-ca-key \ + # --from-file='tls.key=./consul-agent-ca-key.pem' + # ``` + # + # Note that we need the CA key so that we can generate server and client certificates. + # It is particularly important for the client certificates since they need to have host IPs + # as Subject Alternative Names. If you are setting server certs yourself via `server.serverCert` + # and you are not enabling clients (or clients are enabled with autoEncrypt) then you do not + # need to provide the CA key. + caKey: + # The name of the Kubernetes or Vault secret that holds the CA key. + # @type: string + secretName: null + # The key within the Kubernetes or Vault secret that holds the CA key. + # @type: string + secretKey: null + + # This value defines additional annotations for + # tls init jobs. This should be formatted as a multi-line string. + # + # ```yaml + # annotations: | + # "sample/annotation1": "foo" + # "sample/annotation2": "bar" + # ``` + # + # @type: string + annotations: null + + # [Enterprise Only] `enableConsulNamespaces` indicates that you are running + # Consul Enterprise v1.7+ with a valid Consul Enterprise license and would + # like to make use of configuration beyond registering everything into + # the `default` Consul namespace. Additional configuration + # options are found in the `consulNamespaces` section of both the catalog sync + # and connect injector. + enableConsulNamespaces: false + + # Configure ACLs. + acls: + # If true, the Helm chart will automatically manage ACL tokens and policies + # for all Consul and consul-k8s-control-plane components. + # This requires Consul >= 1.4. + manageSystemACLs: false + + # Override global log verbosity level. One of "trace", "debug", "info", "warn", or "error". + # @type: string + logLevel: "" + + # A Kubernetes or Vault secret containing the bootstrap token to use for creating policies and + # tokens for all Consul and consul-k8s-control-plane components. If `secretName` and `secretKey` + # are unset, a default secret name and secret key are used. If the secret is populated, then + # we will skip ACL bootstrapping of the servers and will only initialize ACLs for the Consul + # clients and consul-k8s-control-plane system components. + # If the secret is empty, then we will bootstrap ACLs on the Consul servers, and write the + # bootstrap token to this secret. If ACLs are already bootstrapped on the servers, then the + # secret must contain the bootstrap token. + bootstrapToken: + # The name of the Kubernetes or Vault secret that holds the bootstrap token. + # If unset, this defaults to `{{ global.name }}-bootstrap-acl-token`. + secretName: null + # The key within the Kubernetes or Vault secret that holds the bootstrap token. + # If unset, this defaults to `token`. + secretKey: null + + # If true, an ACL token will be created that can be used in secondary + # datacenters for replication. This should only be set to true in the + # primary datacenter since the replication token must be created from that + # datacenter. + # In secondary datacenters, the secret needs to be imported from the primary + # datacenter and referenced via `global.acls.replicationToken`. + createReplicationToken: false + + # replicationToken references a secret containing the replication ACL token. + # This token will be used by secondary datacenters to perform ACL replication + # and create ACL tokens and policies. + # This value is ignored if `bootstrapToken` is also set. + replicationToken: + # The name of the Kubernetes or Vault secret that holds the replication token. + # @type: string + secretName: null + # The key within the Kubernetes or Vault secret that holds the replication token. + # @type: string + secretKey: null + + # The resource requests (CPU, memory, etc.) for the server-acl-init and server-acl-init-cleanup pods. + # This should be a YAML map corresponding to a Kubernetes + # [`ResourceRequirements``](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#resourcerequirements-v1-core) + # object. + # + # Example: + # + # ```yaml + # resources: + # requests: + # memory: '200Mi' + # cpu: '100m' + # limits: + # memory: '200Mi' + # cpu: '100m' + # ``` + # + # @recurse: false + # @type: map + resources: + requests: + memory: "50Mi" + cpu: "50m" + limits: + memory: "50Mi" + cpu: "50m" + + # partitionToken references a Vault secret containing the ACL token to be used in non-default partitions. + # This value should only be provided in the default partition and only when setting + # the `global.secretsBackend.vault.enabled` value to true. + # Consul will use the value of the secret stored in Vault to create an ACL token in Consul with the value of the + # secret as the secretID for the token. + # In non-default, partitions set this secret as the `bootstrapToken`. + partitionToken: + # The name of the Vault secret that holds the partition token. + # @type: string + secretName: null + # The key within the Vault secret that holds the parition token. + # @type: string + secretKey: null + + # tolerations configures the taints and tolerations for the server-acl-init + # and server-acl-init-cleanup jobs. This should be a multi-line string matching the + # [Tolerations](https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/) array in a Pod spec. + tolerations: "" + + # This value defines [`nodeSelector`](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector) + # labels for the server-acl-init and server-acl-init-cleanup jobs pod assignment, formatted as a multi-line string. + # + # Example: + # + # ```yaml + # nodeSelector: | + # beta.kubernetes.io/arch: amd64 + # ``` + # + # @type: string + nodeSelector: null + + # This value defines additional annotations for + # acl init jobs. This should be formatted as a multi-line string. + # + # ```yaml + # annotations: | + # "sample/annotation1": "foo" + # "sample/annotation2": "bar" + # ``` + # + # @type: string + annotations: null + + # If argocd.enabled is set to true, following annotations are added to + # job - server-acl-init-job + # annotations - + # argocd.argoproj.io/hook: Sync + # argocd.argoproj.io/hook-delete-policy: HookSucceeded + argocd: + enabled: false + + # [Enterprise Only] This value refers to a Kubernetes or Vault secret that you have created + # that contains your enterprise license. It is required if you are using an + # enterprise binary. Defining it here applies it to your cluster once a leader + # has been elected. If you are not using an enterprise image or if you plan to + # introduce the license key via another route, then set these fields to null. + # Note: the job to apply license runs on both Helm installs and upgrades. + enterpriseLicense: + # The name of the Kubernetes or Vault secret that holds the enterprise license. + # A Kubernetes secret must be in the same namespace that Consul is installed into. + # @type: string + secretName: null + # The key within the Kubernetes or Vault secret that holds the enterprise license. + # @type: string + secretKey: null + # Manages license autoload. Required in Consul 1.10.0+, 1.9.7+ and 1.8.12+. + enableLicenseAutoload: true + + # Configure federation. + federation: + # If enabled, this datacenter will be federation-capable. Only federation + # via mesh gateways is supported. + # Mesh gateways and servers will be configured to allow federation. + # Requires `global.tls.enabled`, `connectInject.enabled`, and one of + # `meshGateway.enabled` or `externalServers.enabled` to be true. + # Requires Consul 1.8+. + enabled: false + + # If true, the chart will create a Kubernetes secret that can be imported + # into secondary datacenters so they can federate with this datacenter. The + # secret contains all the information secondary datacenters need to contact + # and authenticate with this datacenter. This should only be set to true + # in your primary datacenter. The secret name is + # `-federation` (if setting `global.name`), otherwise + # `-consul-federation`. + createFederationSecret: false + + # The name of the primary datacenter. + # @type: string + primaryDatacenter: null + + # A list of addresses of the primary mesh gateways in the form `:` + # (e.g. `["1.1.1.1:443", "2.3.4.5:443"]`). + # @type: array + primaryGateways: [] + + # If you are setting `global.federation.enabled` to true and are in a secondary datacenter, + # set `k8sAuthMethodHost` to the address of the Kubernetes API server of the secondary datacenter. + # This address must be reachable from the Consul servers in the primary datacenter. + # This auth method will be used to provision ACL tokens for Consul components and is different + # from the one used by the Consul Service Mesh. + # Please refer to the [Kubernetes Auth Method documentation](https://developer.hashicorp.com/consul/docs/security/acl/auth-methods/kubernetes). + # + # If `externalServers.enabled` is set to true, `global.federation.k8sAuthMethodHost` and + # `externalServers.k8sAuthMethodHost` should be set to the same value. + # + # You can retrieve this value from your `kubeconfig` by running: + # + # ```shell-session + # $ kubectl config view \ + # -o jsonpath="{.clusters[?(@.name=='')].cluster.server}" + # ``` + # + # @type: string + k8sAuthMethodHost: null + + # Override global log verbosity level for the create-federation-secret-job pods. One of "trace", "debug", "info", "warn", or "error". + # @type: string + logLevel: "" + + # Configures metrics for Consul service mesh + metrics: + # Configures the Helm chart’s components + # to expose Prometheus metrics for the Consul service mesh. By default + # this includes gateway metrics and sidecar metrics. + # @type: boolean + enabled: false + + # Configures consul agent metrics. Only applicable if + # `global.metrics.enabled` is true. + # @type: boolean + enableAgentMetrics: false + + # Set to true to stop prepending the machine's hostname to gauge-type metrics. Default is false. + # Only applicable if `global.metrics.enabled` and `global.metrics.enableAgentMetrics` is true. + # @type: boolean + disableAgentHostName: false + + # Configures consul agent underlying host metrics. Default is false. + # Only applicable if `global.metrics.enabled` and `global.metrics.enableAgentMetrics` is true. + # @type: boolean + enableHostMetrics: false + + # Configures the retention time for metrics in Consul clients and + # servers. This must be greater than 0 for Consul clients and servers + # to expose any metrics at all. + # Only applicable if `global.metrics.enabled` is true. + # @type: string + agentMetricsRetentionTime: 1m + + # If true, mesh, terminating, and ingress gateways will expose their + # Envoy metrics on port `20200` at the `/metrics` path and all gateway pods + # will have Prometheus scrape annotations. Only applicable if `global.metrics.enabled` is true. + # @type: boolean + enableGatewayMetrics: true + + # Configures the Helm chart’s components to forward envoy metrics for the Consul service mesh to the + # consul-telemetry-collector. This includes gateway metrics and sidecar metrics. + # @type: boolean + enableTelemetryCollector: false + + # Configures the list of filter rules to apply for allowing or blocking + # metrics by prefix in the following format: + # + # A leading "+" will enable any metrics with the given prefix, and a leading "-" will block them. + # If there is overlap between two rules, the more specific rule will take precedence. + # Blocking will take priority if the same prefix is listed multiple times. + prefixFilter: + # @type: array + allowList: [] + # @type: array + blockList: [] + + # Configures consul integration configurations for datadog on kubernetes. + # Only applicable if `global.metrics.enabled` and `global.metrics.enableAgentMetrics` is true. + datadog: + # Enables datadog [Consul Autodiscovery Integration](https://docs.datadoghq.com/integrations/consul/?tab=containerized#metric-collection) + # by configuring the required `ad.datadoghq.com/consul.checks` annotation. The following _Consul_ agent metrics/health statuses + # are monitored by Datadog unless monitoring via OpenMetrics (Prometheus) or DogStatsD: + # - Serf events and member flaps + # - The Raft protocol + # - DNS performance + # - API Endpoints scraped: + # - `/v1/agent/metrics?format=prometheus` + # - `/v1/agent/self` + # - `/v1/status/leader` + # - `/v1/status/peers` + # - `/v1/catalog/services` + # - `/v1/health/service` + # - `/v1/health/state/any` + # - `/v1/coordinate/datacenters` + # - `/v1/coordinate/nodes` + # + # Setting either `global.metrics.datadog.otlp.enabled=true` or `global.metrics.datadog.dogstatsd.enabled=true` disables the above checks + # in lieu of metrics data collection via DogStatsD or by a customer OpenMetrics (Prometheus) collection endpoint. + # + # ~> **Note:** If you have a [dogstatsd_mapper_profile](https://docs.datadoghq.com/integrations/consul/?tab=host#dogstatsd) configured for Consul + # residing on either your Datadog NodeAgent or ClusterAgent the default Consul agent metrics/health status checks will fail. If you do not desire + # to utilize DogStatsD metrics emission from Consul, remove this configuration file, and restart your Datadog agent to permit the checks to run. + # + # @default: false + # @type: boolean + enabled: false + + # Configures Kubernetes Prometheus/OpenMetrics auto-discovery annotations for use with Datadog. + # This configuration is less common and more for advanced usage with custom metrics monitoring + # configurations. Refer to the [Datadog documentation](https://docs.datadoghq.com/containers/kubernetes/prometheus/?tab=kubernetesadv2) for more details. + openMetricsPrometheus: + # @default: false + # @type: boolean + enabled: false + + otlp: + # Enables forwarding of Consul's Telemetry Collector OTLP metrics for + # ingestion by Datadog Agent. + # @default: false + # @type: boolean + enabled: false + # Protocol used for DataDog Endpoint OTLP ingestion. + # + # Valid protocol options are one of either: + # + # - "http": will forward to DataDog HTTP OTLP Node Agent Endpoint default - "0.0.0.0:4318" + # - "grpc": will forward to DataDog gRPC OTLP Node Agent Endpoint default - "0.0.0.0:4317" + # + # @default: "http" + # @type: string + protocol: "http" + + # Configuration settings for DogStatsD metrics aggregation service + # that is bundled with the Datadog Agent. + # DogStatsD implements the StatsD protocol and adds a few Datadog-specific extensions: + # - Histogram metric type + # - Service checks + # - Events + # - Tagging + dogstatsd: + enabled: false + # Sets the socket transport type for dogstatsd: + # - "UDS" (Unix Domain Socket): prefixes `unix://` to URL and appends path to socket (i.e., "unix:///var/run/datadog/dsd.socket") + # If set, this will create the required [hostPath](https://kubernetes.io/docs/concepts/storage/volumes/#hostpath) mount for + # managing [DogStatsD with Unix Domain Socket on Kubernetes](https://docs.datadoghq.com/developers/dogstatsd/unix_socket/?tab=kubernetes). + # The volume is mounted using the `DirectoryOrCreate` type, thereby setting `0755` permissions with the same kubelet group ownership. + # + # Applies the following `volumes` and `volumeMounts` to the consul-server stateful set consul containers: + # + # ```yaml + # volumes: + # - name: dsdsocket + # hostPath: + # path: /var/run/datadog + # type: DirectoryOrCreate + # volumeMounts: + # - name: dsdsocket + # mountPath: /var/run/datadog + # readOnly: true + # ``` + # - "UDP" (User Datagram Protocol): assigns address to use `hostname/IP:Port` formatted URL for UDP transport to hostIP based + # dogstatsd sink (i.e., 127.0.0.1:8125). HostIP of Datadog agent must be reachable and known to Consul server emitting metrics. + # + # @default: "UDS" + # @type: string + socketTransportType: "UDS" + # Sets URL path for dogstatsd: + # + # Can be either a path to unix domain socket or an IP Address or Hostname that's reachable from the + # consul-server service, server containers. When using "UDS" the path will be appended. When using "UDP" + # the path will be prepended to the specified `dogstatsdPort`. + # + # @default: "/var/run/datadog/dsd.socket" + # @type: string + dogstatsdAddr: "/var/run/datadog/dsd.socket" + # Configures IP based dogstatsd designated port that will be appended to "UDP" based transport socket IP/Hostname URL. + # + # If using a kubernetes service based address (i.e., datadog.default.svc.cluster.local), set this to 0 to + # mitigate appending a port value to the dogstatsd address field. Resultant address would be "datadog.default.svc.cluster.local" with + # default port setting, while appending a non-zero port would result in "172.10.23.6:8125" with a dogstatsdAddr value + # of "172.10.23.6". + # + # @default: 0 + # @type: integer + dogstatsdPort: 0 + # Configures datadog [autodiscovery](https://docs.datadoghq.com/containers/kubernetes/log/?tab=operator#autodiscovery) + # style [log integration](https://docs.datadoghq.com/integrations/consul/?tab=containerized#log-collection) + # configuration for Consul. + # + # The default settings should handle most Consul Kubernetes deployment schemes. The resultant annotation + # will reside on the consul-server statefulset as autodiscovery annotations. + # (i.e., ad.datadoghq.com/consul.logs: ["source:consul","consul_service:consul-server", ""]) + # + # @default: ["source:consul","consul_service:consul-server"] + # @type: array + dogstatsdTags: ["source:consul","consul_service:consul-server"] + # Namespace + # + # @default: "default" + # @type: string + namespace: "default" + + + # The name (and tag) of the consul-dataplane Docker image used for the + # connect-injected sidecar proxies and mesh, terminating, and ingress gateways. + # @default: hashicorp/consul-dataplane: + imageConsulDataplane: hashicorp/consul-dataplane:1.5.3 + + # Configuration for running this Helm chart on the Red Hat OpenShift platform. + # This Helm chart currently supports OpenShift v4.x+. + openshift: + # If true, the Helm chart will create necessary configuration for running + # its components on OpenShift. + enabled: false + + # The time in seconds that the consul API client will wait for a response from + # the API before cancelling the request. + consulAPITimeout: 5s + + # Enables installing an HCP Consul Central self-managed cluster. + # Requires Consul v1.14+. + cloud: + # If true, the Helm chart will link a [self-managed cluster to HCP](https://developer.hashicorp.com/hcp/docs/consul/self-managed). + # This can either be used to [configure a new cluster](https://developer.hashicorp.com/hcp/docs/consul/self-managed/new) + # or [link an existing one](https://developer.hashicorp.com/hcp/docs/consul/self-managed/existing). + # + # Note: this setting should not be enabled for [HCP Consul Dedicated clusters](/hcp/docs/consul/dedicated). + # It is strictly for linking self-managed clusters. + enabled: false + + # The resource id of the HCP Consul Central cluster to link to. Eg: + # organization/27109cd4-a309-4bf3-9986-e1d071914b18/project/fcef6c24-259d-4510-bb8d-1d812e120e34/hashicorp.consul.global-network-manager.cluster/consul-cluster + # This is required when global.cloud.enabled is true. + resourceId: + # The name of the Kubernetes secret that holds the resource id. + # @type: string + secretName: null + # The key within the Kubernetes secret that holds the resource id. + # @type: string + secretKey: null + + # The client id portion of a [service principal](https://developer.hashicorp.com/hcp/docs/hcp/admin/iam/service-principals#service-principals) with authorization to link the cluster + # in global.cloud.resourceId to HCP Consul Central. + # This is required when global.cloud.enabled is true. + clientId: + # The name of the Kubernetes secret that holds the client id. + # @type: string + secretName: null + # The key within the Kubernetes secret that holds the client id. + # @type: string + secretKey: null + + # The client secret portion of a [service principal](https://developer.hashicorp.com/hcp/docs/hcp/admin/iam/service-principals#service-principals) with authorization to link the cluster + # in global.cloud.resourceId to HCP Consul Central. + # This is required when global.cloud.enabled is true. + clientSecret: + # The name of the Kubernetes secret that holds the client secret. + # @type: string + secretName: null + # The key within the Kubernetes secret that holds the client secret. + # @type: string + secretKey: null + + # The hostname of HCP's API. This setting is used for internal testing and validation. + apiHost: + # The name of the Kubernetes secret that holds the api hostname. + # @type: string + secretName: null + # The key within the Kubernetes secret that holds the api hostname. + # @type: string + secretKey: null + + # The URL of HCP's auth API. This setting is used for internal testing and validation. + authUrl: + # The name of the Kubernetes secret that holds the authorization url. + # @type: string + secretName: null + # The key within the Kubernetes secret that holds the authorization url. + # @type: string + secretKey: null + + # The address of HCP's scada service. This setting is used for internal testing and validation. + scadaAddress: + # The name of the Kubernetes secret that holds the scada address. + # @type: string + secretName: null + # The key within the Kubernetes secret that holds the scada address. + # @type: string + secretKey: null + + # Extra labels to attach to all pods, deployments, daemonsets, statefulsets, and jobs. This should be a YAML map. + # + # Example: + # + # ```yaml + # extraLabels: + # labelKey: label-value + # anotherLabelKey: another-label-value + # ``` + # + # @type: map + extraLabels: {} + + # Optional PEM-encoded CA certificates that will be added to trusted system CAs. + # + # Example: + # + # ```yaml + # trustedCAs: [ + # | + # -----BEGIN CERTIFICATE----- + # MIIC7jCCApSgAwIBAgIRAIq2zQEVexqxvtxP6J0bXAwwCgYIKoZIzj0EAwIwgbkx + # ... + # ] + # ``` + # @type: array + trustedCAs: [] + + # Consul feature flags that will be enabled across components. + # Supported feature flags: + # - `v1dns`: + # When this flag is set, Consul agents use the legacy DNS implementation. + # This setting exists in the case a DNS bug is found after the refactoring introduced in v1.19.0. + # + # Example: + # + # ```yaml + # experiments: [ "v1dns" ] + # ``` + # @type: array + experiments: [] + +# Server, when enabled, configures a server cluster to run. This should +# be disabled if you plan on connecting to a Consul cluster external to +# the Kube cluster. +server: + # If true, the chart will install all the resources necessary for a + # Consul server cluster. If you're running Consul externally and want agents + # within Kubernetes to join that cluster, this should probably be false. + # @default: global.enabled + # @type: boolean + enabled: "-" + + # Override global log verbosity level. One of "trace", "debug", "info", "warn", or "error". + # @type: string + logLevel: "" + + # The name of the Docker image (including any tag) for the containers running + # Consul server agents. + # @type: string + image: null + + # The number of server agents to run. This determines the fault tolerance of + # the cluster. Please refer to the [deployment table](https://developer.hashicorp.com/consul/docs/architecture/consensus#deployment-table) + # for more information. + replicas: 3 + + # The number of servers that are expected to be running. + # It defaults to server.replicas. + # In most cases the default should be used, however if there are more + # servers in this datacenter than server.replicas it might make sense + # to override the default. This would be the case if two kube clusters + # were joined into the same datacenter and each cluster ran a certain number + # of servers. + # @type: int + bootstrapExpect: null + + # A secret containing a certificate & key for the server agents to use + # for TLS communication within the Consul cluster. Cert needs to be provided with + # additional DNS name SANs so that it will work within the Kubernetes cluster: + # + # Kubernetes Secrets backend: + # ```bash + # consul tls cert create -server -days=730 -domain=consul -ca=consul-agent-ca.pem \ + # -key=consul-agent-ca-key.pem -dc={{datacenter}} \ + # -additional-dnsname="{{fullname}}-server" \ + # -additional-dnsname="*.{{fullname}}-server" \ + # -additional-dnsname="*.{{fullname}}-server.{{namespace}}" \ + # -additional-dnsname="*.{{fullname}}-server.{{namespace}}.svc" \ + # -additional-dnsname="*.server.{{datacenter}}.{{domain}}" \ + # -additional-dnsname="server.{{datacenter}}.{{domain}}" + # ``` + # + # If you have generated the server-cert yourself with the consul CLI, you could use the following command + # to create the secret in Kubernetes: + # + # ```bash + # kubectl create secret generic consul-server-cert \ + # --from-file='tls.crt=./dc1-server-consul-0.pem' + # --from-file='tls.key=./dc1-server-consul-0-key.pem' + # ``` + # + # Vault Secrets backend: + # If you are using Vault as a secrets backend, a Vault Policy must be created which allows `["create", "update"]` + # capabilities on the PKI issuing endpoint, which is usually of the form `pki/issue/consul-server`. + # Complete [this tutorial](https://developer.hashicorp.com/consul/tutorials/vault-secure/vault-pki-consul-secure-tls) + # to learn how to generate a compatible certificate. + # Note: when using TLS, both the `server.serverCert` and `global.tls.caCert` which points to the CA endpoint of this PKI engine + # must be provided. + serverCert: + # The name of the Vault secret that holds the PEM encoded server certificate. + # @type: string + secretName: null + + # Exposes the servers' gossip and RPC ports as hostPorts. To enable a client + # agent outside of the k8s cluster to join the datacenter, you would need to + # enable `server.exposeGossipAndRPCPorts`, `client.exposeGossipPorts`, and + # set `server.ports.serflan.port` to a port not being used on the host. Since + # `client.exposeGossipPorts` uses the hostPort 8301, + # `server.ports.serflan.port` must be set to something other than 8301. + exposeGossipAndRPCPorts: false + + # Configures ports for the consul servers. + ports: + # Configures the LAN gossip port for the consul servers. If you choose to + # enable `server.exposeGossipAndRPCPorts` and `client.exposeGossipPorts`, + # that will configure the LAN gossip ports on the servers and clients to be + # hostPorts, so if you are running clients and servers on the same node the + # ports will conflict if they are both 8301. When you enable + # `server.exposeGossipAndRPCPorts` and `client.exposeGossipPorts`, you must + # change this from the default to an unused port on the host, e.g. 9301. By + # default the LAN gossip port is 8301 and configured as a containerPort on + # the consul server Pods. + serflan: + port: 8301 + + # This defines the disk size for configuring the + # servers' StatefulSet storage. For dynamically provisioned storage classes, this is the + # desired size. For manually defined persistent volumes, this should be set to + # the disk size of the attached volume. + storage: 10Gi + + # The StorageClass to use for the servers' StatefulSet storage. It must be + # able to be dynamically provisioned if you want the storage + # to be automatically created. For example, to use + # local(https://kubernetes.io/docs/concepts/storage/storage-classes/#local) + # storage classes, the PersistentVolumeClaims would need to be manually created. + # A `null` value will use the Kubernetes cluster's default StorageClass. If a default + # StorageClass does not exist, you will need to create one. + # Refer to the [Read/Write Tuning](https://developer.hashicorp.com/consul/docs/install/performance#read-write-tuning) + # section of the Server Performance Requirements documentation for considerations + # around choosing a performant storage class. + # + # ~> **Note:** The [Reference Architecture](https://developer.hashicorp.com/consul/tutorials/production-deploy/reference-architecture#hardware-sizing-for-consul-servers) + # contains best practices and recommendations for selecting suitable + # hardware sizes for your Consul servers. + # @type: string + storageClass: null + + # The [Persistent Volume Claim (PVC) retention policy](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#persistentvolumeclaim-retention) + # controls if and how PVCs are deleted during the lifecycle of a StatefulSet. + # WhenDeleted specifies what happens to PVCs created from StatefulSet VolumeClaimTemplates when the StatefulSet is deleted, + # and WhenScaled specifies what happens to PVCs created from StatefulSet VolumeClaimTemplates when the StatefulSet is scaled down. + # + # Example: + # + # ```yaml + # persistentVolumeClaimRetentionPolicy: + # whenDeleted: Retain + # whenScaled: Retain + # ``` + # @type: map + persistentVolumeClaimRetentionPolicy: null + + # This will enable/disable [service mesh](https://developer.hashicorp.com/consul/docs/connect). Setting this to true + # _will not_ automatically secure pod communication, this + # setting will only enable usage of the feature. Consul will automatically initialize + # a new CA and set of certificates. Additional service mesh settings can be configured + # by setting the `server.extraConfig` value or by applying [configuration entries](https://developer.hashicorp.com/consul/docs/connect/config-entries). + connect: true + + # When set to true, enables Consul to report additional debugging information, including runtime profiling (pprof) data. + # This setting is only required for clusters without ACL enabled. Sets `enable_debug` in server agent config to `true`. + # If you change this setting, you must restart the agent for the change to take effect. Default is false. + # @type: boolean + enableAgentDebug: false + + serviceAccount: + # This value defines additional annotations for the server service account. This should be formatted as a multi-line + # string. + # + # ```yaml + # annotations: | + # "sample/annotation1": "foo" + # "sample/annotation2": "bar" + # ``` + # + # @type: string + annotations: null + + # The resource requests (CPU, memory, etc.) + # for each of the server agents. This should be a YAML map corresponding to a Kubernetes + # [`ResourceRequirements``](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#resourcerequirements-v1-core) + # object. NOTE: The use of a YAML string is deprecated. + # + # Example: + # + # ```yaml + # resources: + # requests: + # memory: '200Mi' + # cpu: '100m' + # limits: + # memory: '200Mi' + # cpu: '100m' + # ``` + # + # @recurse: false + # @type: map + resources: + requests: + memory: "200Mi" + cpu: "100m" + limits: + memory: "200Mi" + cpu: "100m" + + # The security context for the server pods. This should be a YAML map corresponding to a + # Kubernetes [SecurityContext](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) object. + # By default, servers will run as non-root, with user ID `100` and group ID `1000`, + # which correspond to the consul user and group created by the Consul docker image. + # Note: if running on OpenShift, this setting is ignored because the user and group are set automatically + # by the OpenShift platform. + # @type: map + # @recurse: false + securityContext: + runAsNonRoot: true + runAsGroup: 1000 + runAsUser: 100 + fsGroup: 1000 + + # The container securityContext for each container in the server pods. In + # addition to the Pod's SecurityContext this can + # set the capabilities of processes running in the container and ensure the + # root file systems in the container is read-only. + # @type: map + # @recurse: true + containerSecurityContext: + # The consul server agent container + # @type: map + # @recurse: false + server: null + # The acl-init job + # @type: map + # @recurse: false + aclInit: null + # The tls-init job + # @type: map + # @recurse: false + tlsInit: null + + # This value is used to carefully + # control a rolling update of Consul server agents. This value specifies the + # [partition](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#partitions) + # for performing a rolling update. Please read the linked Kubernetes + # and [Upgrade Consul](https://developer.hashicorp.com/consul/docs/k8s/upgrade#upgrading-consul-servers) + # documentation for more information. + updatePartition: 0 + + # This configures the [`PodDisruptionBudget`](https://kubernetes.io/docs/tasks/run-application/configure-pdb/) + # for the server cluster. + disruptionBudget: + # Enables registering a PodDisruptionBudget for the server + # cluster. If enabled, it only registers the budget so long as + # the server cluster is enabled. To disable, set to `false`. + enabled: true + + # The maximum number of unavailable pods. In most cases you should not change this as it is automatically set to + # the correct number when left as null. This setting has been kept to preserve backwards compatibility. + # + # By default, this is set to 1 internally in the chart. When server pods are stopped gracefully, they leave the Raft + # consensus pool. When running an odd number of servers, one server leaving the pool does not change the quorum + # size, and so fault tolerance is not affected. However, if more than one server were to leave the pool, the quorum + # size would change. That's why this is set to 1 internally and should not be changed in most cases. + # + # If you need to set this to `0`, you will need to add a + # --set 'server.disruptionBudget.maxUnavailable=0'` flag to the helm chart installation + # command because of a limitation in the Helm templating language. + # @type: integer + maxUnavailable: null + + # A raw string of extra [JSON configuration](https://developer.hashicorp.com/consul/docs/agent/config/config-files) for Consul + # servers. This will be saved as-is into a ConfigMap that is read by the Consul + # server agents. This can be used to add additional configuration that + # isn't directly exposed by the chart. + # + # Example: + # + # ```yaml + # extraConfig: | + # { + # "log_level": "DEBUG" + # } + # ``` + # + # This can also be set using Helm's `--set` flag using the following syntax: + # + # ```shell-session + # --set 'server.extraConfig="{"log_level": "DEBUG"}"' + # ``` + extraConfig: | + {} + + # A list of extra volumes to mount for server agents. This + # is useful for bringing in extra data that can be referenced by other configurations + # at a well known path, such as TLS certificates or Gossip encryption keys. The + # value of this should be a list of objects. + # + # Example: + # + # ```yaml + # extraVolumes: + # - type: secret + # name: consul-certs + # load: false + # ``` + # + # Each object supports the following keys: + # + # - `type` - Type of the volume, must be one of "configMap" or "secret". Case sensitive. + # + # - `name` - Name of the configMap or secret to be mounted. This also controls + # the path that it is mounted to. The volume will be mounted to `/consul/userconfig/`. + # + # - `load` - If true, then the agent will be + # configured to automatically load HCL/JSON configuration files from this volume + # with `-config-dir`. This defaults to false. + # + # @type: array + extraVolumes: [] + + # A list of sidecar containers. + # Example: + # + # ```yaml + # extraContainers: + # - name: extra-container + # image: example-image:latest + # command: + # - ... + # ``` + # @type: array + extraContainers: [] + + # This value defines the [affinity](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity) + # for server pods. It defaults to allowing only a single server pod on each node, which + # minimizes risk of the cluster becoming unusable if a node is lost. If you need + # to run more pods per node (for example, testing on Minikube), set this value + # to `null`. + # + # Example: + # + # ```yaml + # affinity: | + # podAntiAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # - labelSelector: + # matchLabels: + # app: {{ template "consul.name" . }} + # release: "{{ .Release.Name }}" + # component: server + # topologyKey: kubernetes.io/hostname + # ``` + affinity: | + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app: {{ template "consul.name" . }} + release: "{{ .Release.Name }}" + component: server + topologyKey: kubernetes.io/hostname + + # Toleration settings for server pods. This + # should be a multi-line string matching the + # [Tolerations](https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/) + # array in a Pod spec. + tolerations: "" + + # Pod topology spread constraints for server pods. + # This should be a multi-line YAML string matching the + # [`topologySpreadConstraints`](https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/) + # array in a Pod Spec. + # + # This requires K8S >= 1.18 (beta) or 1.19 (stable). + # + # Example: + # + # ```yaml + # topologySpreadConstraints: | + # - maxSkew: 1 + # topologyKey: topology.kubernetes.io/zone + # whenUnsatisfiable: DoNotSchedule + # labelSelector: + # matchLabels: + # app: {{ template "consul.name" . }} + # release: "{{ .Release.Name }}" + # component: server + # ``` + topologySpreadConstraints: "" + + # This value defines [`nodeSelector`](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector) + # labels for server pod assignment, formatted as a multi-line string. + # + # Example: + # + # ```yaml + # nodeSelector: | + # beta.kubernetes.io/arch: amd64 + # ``` + # + # @type: string + nodeSelector: null + + # This value references an existing + # Kubernetes [`priorityClassName`](https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#pod-priority) + # that can be assigned to server pods. + priorityClassName: "" + + # Extra labels to attach to the server pods. This should be a YAML map. + # + # Example: + # + # ```yaml + # extraLabels: + # labelKey: label-value + # anotherLabelKey: another-label-value + # ``` + # + # @type: map + extraLabels: null + + # This value defines additional annotations for + # server pods. This should be formatted as a multi-line string. + # + # ```yaml + # annotations: | + # "sample/annotation1": "foo" + # "sample/annotation2": "bar" + # ``` + # + # @type: string + annotations: null + + # Configures a service to expose ports on the Consul servers over a Kubernetes Service. + exposeService: + # When enabled, deploys a Kubernetes Service to reach the Consul servers. + # @type: boolean + enabled: "-" + # Type of service, supports LoadBalancer or NodePort. + # @type: string + type: LoadBalancer + # If service is of type NodePort, configures the nodePorts. + nodePort: + # Configures the nodePort to expose the Consul server http port. + # @type: integer + http: null + # Configures the nodePort to expose the Consul server https port. + # @type: integer + https: null + # Configures the nodePort to expose the Consul server serf port. + # @type: integer + serf: null + # Configures the nodePort to expose the Consul server rpc port. + # @type: integer + rpc: null + # Configures the nodePort to expose the Consul server grpc port. + # @type: integer + grpc: null + # This value defines additional annotations for + # server pods. This should be formatted as a multi-line string. + # + # ```yaml + # annotations: | + # "sample/annotation1": "foo" + # "sample/annotation2": "bar" + # ``` + # + # @type: string + annotations: null + + # Server service properties. + service: + # Annotations to apply to the server service. + # + # ```yaml + # annotations: | + # "annotation-key": "annotation-value" + # ``` + # + # @type: string + annotations: null + + # A list of extra environment variables to set within the stateful set. + # These could be used to include proxy settings required for cloud auto-join + # feature, in case kubernetes cluster is behind egress http proxies. Additionally, + # it could be used to configure custom consul parameters. + # @type: map + extraEnvironmentVars: {} + + # [Enterprise Only] Values for setting up and running + # [snapshot agents](https://developer.hashicorp.com/consul/commands/snapshot/agent) + # within the Consul clusters. They run as a sidecar with Consul servers. + snapshotAgent: + # If true, the chart will install resources necessary to run the snapshot agent. + enabled: false + + # Interval at which to perform snapshots. + # Refer to [`interval`](https://developer.hashicorp.com/consul/commands/snapshot/agent#interval) + # @type: string + interval: 1h + + # A Kubernetes or Vault secret that should be manually created to contain the entire + # config to be used on the snapshot agent. + # This is the preferred method of configuration since there are usually storage + # credentials present. Please refer to the [Snapshot agent config](https://developer.hashicorp.com/consul/commands/snapshot/agent#config-file-options) + # for details. + configSecret: + # The name of the Kubernetes secret or Vault secret path that holds the snapshot agent config. + # @type: string + secretName: null + # The key within the Kubernetes secret or Vault secret key that holds the snapshot agent config. + # @type: string + secretKey: null + + # The resource settings for snapshot agent pods. + # @recurse: false + # @type: map + resources: + requests: + memory: "50Mi" + cpu: "50m" + limits: + memory: "50Mi" + cpu: "50m" + + # Optional PEM-encoded CA certificate that will be added to the trusted system CAs. + # Useful if using an S3-compatible storage exposing a self-signed certificate. + # + # Example: + # + # ```yaml + # caCert: | + # -----BEGIN CERTIFICATE----- + # MIIC7jCCApSgAwIBAgIRAIq2zQEVexqxvtxP6J0bXAwwCgYIKoZIzj0EAwIwgbkx + # ... + # ``` + # @type: string + caCert: null + + # [Enterprise Only] Added in Consul 1.8, the audit object allow users to enable auditing + # and configure a sink and filters for their audit logs. Please refer to + # [audit logs](https://developer.hashicorp.com/consul/docs/enterprise/audit-logging) documentation + # for further information. + auditLogs: + # Controls whether Consul logs out each time a user performs an operation. + # global.acls.manageSystemACLs must be enabled to use this feature. + enabled: false + + # A single entry of the sink object provides configuration for the destination to which Consul + # will log auditing events. + # + # Example: + # + # ```yaml + # sinks: + # - name: My Sink + # type: file + # format: json + # path: /tmp/audit.json + # delivery_guarantee: best-effort + # rotate_duration: 24h + # rotate_max_files: 15 + # rotate_bytes: 25165824 + # + # ``` + # + # The sink object supports the following keys: + # + # - `name` - Name of the sink. + # + # - `type` - Type specifies what kind of sink this is. Currently only file sinks are available + # + # - `format` - Format specifies what format the events will be emitted with. Currently only `json` + # events are emitted. + # + # - `path` - The directory and filename to write audit events to. + # + # - `delivery_guarantee` - Specifies the rules governing how audit events are written. Consul + # only supports `best-effort` event delivery. + # + # - `mode` - The permissions to set on the audit log files. + # + # - `rotate_duration` - Specifies the interval by which the system rotates to a new log file. + # At least one of `rotate_duration` or `rotate_bytes` must be configured to enable audit logging. + # + # - `rotate_bytes` - Specifies how large an individual log file can grow before Consul rotates to a new file. + # At least one of rotate_bytes or rotate_duration must be configured to enable audit logging. + # + # - `rotate_max_files` - Defines the limit that Consul should follow before it deletes old log files. + # + # @type: array + sinks: [] + + # Settings for potentially limiting timeouts, rate limiting on clients as well + # as servers, and other settings to limit exposure too many requests, requests + # waiting for too long, and other runtime considerations. + limits: + # This object specifies configurations that limit the rate of RPC and gRPC + # requests on the Consul server. Limiting the rate of gRPC and RPC requests + # also limits HTTP requests to the Consul server. + # https://developer.hashicorp.com/consul/docs/agent/config/config-files#request_limits + requestLimits: + # Setting for disabling or enabling rate limiting. If not disabled, it + # enforces the action that will occur when RequestLimitsReadRate + # or RequestLimitsWriteRate is exceeded. The default value of "disabled" will + # prevent any rate limiting from occuring. A value of "enforce" will block + # the request from processings by returning an error. A value of + # "permissive" will not block the request and will allow the request to + # continue processing. + # @type: string + mode: "disabled" + + # Setting that controls how frequently RPC, gRPC, and HTTP + # queries are allowed to happen. In any large enough time interval, rate + # limiter limits the rate to RequestLimitsReadRate tokens per second. + # + # See https://en.wikipedia.org/wiki/Token_bucket for more about token + # buckets. + # @type: integer + readRate: -1 + + # Setting that controls how frequently RPC, gRPC, and HTTP + # writes are allowed to happen. In any large enough time interval, rate + # limiter limits the rate to RequestLimitsWriteRate tokens per second. + # + # See https://en.wikipedia.org/wiki/Token_bucket for more about token + # buckets. + # @type: integer + writeRate: -1 + +# Configuration for Consul servers when the servers are running outside of Kubernetes. +# When running external servers, configuring these values is recommended +# if setting `global.tls.enableAutoEncrypt` to true +# or `global.acls.manageSystemACLs` to true. +externalServers: + # If true, the Helm chart will be configured to talk to the external servers. + # If setting this to true, you must also set `server.enabled` to false. + enabled: false + + # An array of external Consul server hosts that are used to make + # HTTPS connections from the components in this Helm chart. + # Valid values include an IP, a DNS name, or an [exec=](https://github.com/hashicorp/go-netaddrs) string. + # The port must be provided separately below. + # Note: This slice can only contain a single element. + # Note: If enabling clients, `client.join` must also be set to the hosts that should be + # used to join the cluster. In most cases, the `client.join` values + # should be the same, however, they may be different if you + # wish to use separate hosts for the HTTPS connections. `tlsServerName` is required if TLS is enabled and 'hosts' is not a DNS name. + # @type: array + hosts: [] + + # The HTTPS port of the Consul servers. + httpsPort: 8501 + + # The GRPC port of the Consul servers. + grpcPort: 8502 + + # The server name to use as the SNI host header when connecting with HTTPS. This name also appears as the hostname in the server certificate's subject field. + # @type: string + tlsServerName: null + + # If true, consul-k8s-control-plane components will ignore the CA set in + # `global.tls.caCert` when making HTTPS calls to Consul servers and + # will instead use the consul-k8s-control-plane image's system CAs for TLS verification. + # If false, consul-k8s-control-plane components will use `global.tls.caCert` when + # making HTTPS calls to Consul servers. + # **NOTE:** This does not affect Consul's internal RPC communication which will + # always use `global.tls.caCert`. + useSystemRoots: false + + # If you are setting `global.acls.manageSystemACLs` and + # `connectInject.enabled` to true, set `k8sAuthMethodHost` to the address of the Kubernetes API server. + # This address must be reachable from the Consul servers. + # Please refer to the [Kubernetes Auth Method documentation](https://developer.hashicorp.com/consul/docs/security/acl/auth-methods/kubernetes). + # + # If `global.federation.enabled` is set to true, `global.federation.k8sAuthMethodHost` and + # `externalServers.k8sAuthMethodHost` should be set to the same value. + # + # You could retrieve this value from your `kubeconfig` by running: + # + # ```shell-session + # $ kubectl config view \ + # -o jsonpath="{.clusters[?(@.name=='')].cluster.server}" + # ``` + # + # @type: string + k8sAuthMethodHost: null + + # If true, setting this prevents the consul-dataplane and consul-k8s components from watching the Consul servers for changes. This is + # useful for situations where Consul servers are behind a load balancer. + skipServerWatch: false + +# Values that configure running a Consul client on Kubernetes nodes. +client: + # If true, the chart will install all + # the resources necessary for a Consul client on every Kubernetes node. This _does not_ require + # `server.enabled`, since the agents can be configured to join an external cluster. + # @type: boolean + enabled: false + + # Override global log verbosity level. One of "trace", "debug", "info", "warn", or "error". + # @type: string + logLevel: "" + + # The name of the Docker image (including any tag) for the containers + # running Consul client agents. + # @type: string + image: null + + # A list of valid [`-retry-join` values](https://developer.hashicorp.com/consul/docs/agent/config/cli-flags#_retry_join). + # If this is `null` (default), then the clients will attempt to automatically + # join the server cluster running within Kubernetes. + # This means that with `server.enabled` set to true, clients will automatically + # join that cluster. If `server.enabled` is not true, then a value must be + # specified so the clients can join a valid cluster. + # @type: array + join: null + + # An absolute path to a directory on the host machine to use as the Consul + # client data directory. If set to the empty string or null, the Consul agent + # will store its data in the Pod's local filesystem (which will + # be lost if the Pod is deleted). Security Warning: If setting this, Pod Security + # Policies _must_ be enabled on your cluster and in this Helm chart (via the + # `global.enablePodSecurityPolicies` setting) to prevent other pods from + # mounting the same host path and gaining access to all of Consul's data. + # Consul's data is not encrypted at rest. + # @type: string + dataDirectoryHostPath: null + + # If true, agents will enable their GRPC listener on + # port 8502 and expose it to the host. This will use slightly more resources, but is + # required for Connect. + grpc: true + + # nodeMeta specifies an arbitrary metadata key/value pair to associate with the node + # (refer to [`-node-meta`](https://developer.hashicorp.com/consul/docs/agent/config/cli-flags#_node_meta)) + nodeMeta: + pod-name: ${HOSTNAME} + host-ip: ${HOST_IP} + + # If true, the Helm chart will expose the clients' gossip ports as hostPorts. + # This is only necessary if pod IPs in the k8s cluster are not directly routable + # and the Consul servers are outside of the k8s cluster. + # This also changes the clients' advertised IP to the `hostIP` rather than `podIP`. + exposeGossipPorts: false + + serviceAccount: + # This value defines additional annotations for the client service account. This should be formatted as a multi-line + # string. + # + # ```yaml + # annotations: | + # "sample/annotation1": "foo" + # "sample/annotation2": "bar" + # ``` + # + # @type: string + annotations: null + + # The resource settings for Client agents. + # NOTE: The use of a YAML string is deprecated. Instead, set directly as a + # YAML map. + # @recurse: false + # @type: map + resources: + requests: + memory: "100Mi" + cpu: "100m" + limits: + memory: "100Mi" + cpu: "100m" + + # The security context for the client pods. This should be a YAML map corresponding to a + # Kubernetes [SecurityContext](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) object. + # By default, servers will run as non-root, with user ID `100` and group ID `1000`, + # which correspond to the consul user and group created by the Consul docker image. + # Note: if running on OpenShift, this setting is ignored because the user and group are set automatically + # by the OpenShift platform. + # @type: map + # @recurse: false + securityContext: + runAsNonRoot: true + runAsGroup: 1000 + runAsUser: 100 + fsGroup: 1000 + + # The container securityContext for each container in the client pods. In + # addition to the Pod's SecurityContext this can + # set the capabilities of processes running in the container and ensure the + # root file systems in the container is read-only. + # @type: map + # @recurse: true + containerSecurityContext: + # The consul client agent container + # @type: map + # @recurse: false + client: null + # The acl-init initContainer + # @type: map + # @recurse: false + aclInit: null + # The tls-init initContainer + # @type: map + # @recurse: false + tlsInit: null + + # A raw string of extra [JSON configuration](https://developer.hashicorp.com/consul/docs/agent/config/config-files) for Consul + # clients. This will be saved as-is into a ConfigMap that is read by the Consul + # client agents. This can be used to add additional configuration that + # isn't directly exposed by the chart. + # + # Example: + # + # ```yaml + # extraConfig: | + # { + # "log_level": "DEBUG" + # } + # ``` + # + # This can also be set using Helm's `--set` flag using the following syntax: + # + # ```shell-session + # --set 'client.extraConfig="{"log_level": "DEBUG"}"' + # ``` + extraConfig: | + {} + + # A list of extra volumes to mount for client agents. This + # is useful for bringing in extra data that can be referenced by other configurations + # at a well known path, such as TLS certificates or Gossip encryption keys. The + # value of this should be a list of objects. + # + # Example: + # + # ```yaml + # extraVolumes: + # - type: secret + # name: consul-certs + # load: false + # ``` + # + # Each object supports the following keys: + # + # - `type` - Type of the volume, must be one of "configMap" or "secret". Case sensitive. + # + # - `name` - Name of the configMap or secret to be mounted. This also controls + # the path that it is mounted to. The volume will be mounted to `/consul/userconfig/`. + # + # - `load` - If true, then the agent will be + # configured to automatically load HCL/JSON configuration files from this volume + # with `-config-dir`. This defaults to false. + # + # @type: array + extraVolumes: [] + + # A list of sidecar containers. + # Example: + # + # ```yaml + # extraContainers: + # - name: extra-container + # image: example-image:latest + # command: + # - ... + # ``` + # @type: array + extraContainers: [] + + # Toleration Settings for Client pods + # This should be a multi-line string matching the Toleration array + # in a PodSpec. + # The example below will allow Client pods to run on every node + # regardless of taints + # + # ```yaml + # tolerations: | + # - operator: Exists + # ``` + tolerations: "" + + # nodeSelector labels for client pod assignment, formatted as a multi-line string. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector + # + # Example: + # + # ```yaml + # nodeSelector: | + # beta.kubernetes.io/arch: amd64 + # ``` + # @type: string + nodeSelector: null + + # Affinity Settings for Client pods, formatted as a multi-line YAML string. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + # + # Example: + # + # ```yaml + # affinity: | + # nodeAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # nodeSelectorTerms: + # - matchExpressions: + # - key: node-role.kubernetes.io/master + # operator: DoesNotExist + # ``` + # @type: string + affinity: null + + # This value references an existing + # Kubernetes [`priorityClassName`](https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#pod-priority) + # that can be assigned to client pods. + priorityClassName: "" + + # This value defines additional annotations for + # client pods. This should be formatted as a multi-line string. + # + # ```yaml + # annotations: | + # "sample/annotation1": "foo" + # "sample/annotation2": "bar" + # ``` + # + # @type: string + annotations: null + + # Extra labels to attach to the client pods. This should be a regular YAML map. + # + # Example: + # + # ```yaml + # extraLabels: + # labelKey: label-value + # anotherLabelKey: another-label-value + # ``` + # + # @type: map + extraLabels: null + + # A list of extra environment variables to set within the stateful set. + # These could be used to include proxy settings required for cloud auto-join + # feature, in case kubernetes cluster is behind egress http proxies. Additionally, + # it could be used to configure custom consul parameters. + # @type: map + extraEnvironmentVars: {} + + # This value defines the [Pod DNS policy](https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-policy) + # for client pods to use. + # @type: string + dnsPolicy: null + + # hostNetwork defines whether or not we use host networking instead of hostPort in the event + # that a CNI plugin doesn't support `hostPort`. This has security implications and is not recommended + # as doing so gives the consul client unnecessary access to all network traffic on the host. + # In most cases, pod network and host network are on different networks so this should be + # combined with `dnsPolicy: ClusterFirstWithHostNet` + hostNetwork: false + + # updateStrategy for the DaemonSet. + # Refer to the Kubernetes [Daemonset upgrade strategy](https://kubernetes.io/docs/tasks/manage-daemon/update-daemon-set/#daemonset-update-strategy) + # documentation. + # This should be a multi-line string mapping directly to the updateStrategy + # + # Example: + # + # ```yaml + # updateStrategy: | + # rollingUpdate: + # maxUnavailable: 5 + # type: RollingUpdate + # ``` + # + # @type: string + updateStrategy: null + +# Configuration for DNS configuration within the Kubernetes cluster. +# This creates a service that routes to all agents (client or server) +# for serving DNS requests. This DOES NOT automatically configure kube-dns +# today, so you must still manually configure a `stubDomain` with kube-dns +# for this to have any effect: +# https://kubernetes.io/docs/tasks/administer-cluster/dns-custom-nameservers/#configure-stub-domain-and-upstream-dns-servers +dns: + # @type: boolean + enabled: "-" + + # If true, services using Consul service mesh will use Consul DNS + # for default DNS resolution. The DNS lookups fall back to the nameserver IPs + # listed in /etc/resolv.conf if not found in Consul. + # @type: boolean + enableRedirection: "-" + + # Used to control the type of service created. For + # example, setting this to "LoadBalancer" will create an external load + # balancer (for supported K8S installations) + type: ClusterIP + + # Set a predefined cluster IP for the DNS service. + # Useful if you need to reference the DNS service's IP + # address in CoreDNS config. + # @type: string + clusterIP: null + + # Extra annotations to attach to the dns service + # This should be a multi-line string of + # annotations to apply to the dns Service + # @type: string + annotations: null + + # Additional ServiceSpec values + # This should be a multi-line string mapping directly to a Kubernetes + # ServiceSpec object. + # @type: string + additionalSpec: null + +# Values that configure the Consul UI. +ui: + # If true, the UI will be enabled. This will + # only _enable_ the UI, it doesn't automatically register any service for external + # access. The UI will only be enabled on server agents. If `server.enabled` is + # false, then this setting has no effect. To expose the UI in some way, you must + # configure `ui.service`. + # @default: global.enabled + # @type: boolean + enabled: "-" + + # Configure the service for the Consul UI. + service: + # This will enable/disable registering a + # Kubernetes Service for the Consul UI. This value only takes effect if `ui.enabled` is + # true and taking effect. + enabled: true + + # The service type to register. + # @type: string + type: null + + # Set the port value of the UI service. + port: + # HTTP port. + http: 80 + + # HTTPS port. + https: 443 + + # Optionally set the nodePort value of the ui service if using a NodePort service. + # If not set and using a NodePort service, Kubernetes will automatically assign + # a port. + nodePort: + # HTTP node port + # @type: integer + http: null + + # HTTPS node port + # @type: integer + https: null + + # Annotations to apply to the UI service. + # + # Example: + # + # ```yaml + # annotations: | + # 'annotation-key': annotation-value + # ``` + # @type: string + annotations: null + + # Additional ServiceSpec values + # This should be a multi-line string mapping directly to a Kubernetes + # ServiceSpec object. + # @type: string + additionalSpec: null + + # Configure Ingress for the Consul UI. + # If `global.tls.enabled` is set to `true`, the Ingress will expose + # the port 443 on the UI service. Please ensure the Ingress Controller + # supports SSL pass-through and it is enabled to ensure traffic forwarded + # to port 443 has not been TLS terminated. + ingress: + # This will create an Ingress resource for the Consul UI. + # @type: boolean + enabled: false + + # Optionally set the ingressClassName. + ingressClassName: "" + + # pathType override - refer to: https://kubernetes.io/docs/concepts/services-networking/ingress/#path-types + pathType: Prefix + + # hosts is a list of host name to create Ingress rules. + # + # ```yaml + # hosts: + # - host: foo.bar + # paths: + # - /example + # - /test + # ``` + # + # @type: array + hosts: [] + + # tls is a list of hosts and secret name in an Ingress + # which tells the Ingress controller to secure the channel. + # + # ```yaml + # tls: + # - hosts: + # - chart-example.local + # secretName: testsecret-tls + # ``` + # @type: array + tls: [] + + # Annotations to apply to the UI ingress. + # + # Example: + # + # ```yaml + # annotations: | + # 'annotation-key': annotation-value + # ``` + # @type: string + annotations: null + + # Configurations for displaying metrics in the UI. + metrics: + # Enable displaying metrics in the UI. The default value of "-" + # will inherit from `global.metrics.enabled` value. + # @type: boolean + # @default: global.metrics.enabled + enabled: "-" + # Provider for metrics. Refer to + # [`metrics_provider`](https://developer.hashicorp.com/consul/docs/agent/config/config-files#ui_config_metrics_provider) + # This value is only used if `ui.enabled` is set to true. + # @type: string + provider: "prometheus" + + # baseURL is the URL of the prometheus server, usually the service URL. + # This value is only used if `ui.enabled` is set to true. + # @type: string + baseURL: http://prometheus-server + + # Corresponds to [`dashboard_url_templates`](https://developer.hashicorp.com/consul/docs/agent/config/config-files#ui_config_dashboard_url_templates) + # configuration. + dashboardURLTemplates: + # Sets [`dashboardURLTemplates.service`](https://developer.hashicorp.com/consul/docs/agent/config/config-files#ui_config_dashboard_url_templates_service). + service: "" + +# Configure the catalog sync process to sync K8S with Consul +# services. This can run bidirectional (default) or unidirectionally (Consul +# to K8S or K8S to Consul only). +# +# This process assumes that a Consul agent is available on the host IP. +# This is done automatically if clients are enabled. If clients are not +# enabled then set the node selection so that it chooses a node with a +# Consul agent. +syncCatalog: + # True if you want to enable the catalog sync. Set to "-" to inherit from + # global.enabled. + enabled: false + + # The name of the Docker image (including any tag) for consul-k8s-control-plane + # to run the sync program. + # @type: string + image: null + + # If true, all valid services in K8S are + # synced by default. If false, the service must be [annotated](https://developer.hashicorp.com/consul/docs/k8s/service-sync#enable-and-disable-sync) + # properly to sync. + # In either case an annotation can override the default. + default: true + + # Optional priorityClassName. + priorityClassName: "" + + # If true, will sync Kubernetes services to Consul. This can be disabled to + # have a one-way sync. + toConsul: true + + # If true, will sync Consul services to Kubernetes. This can be disabled to + # have a one-way sync. + toK8S: true + + # Service prefix to prepend to services before registering + # with Kubernetes. For example "consul-" will register all services + # prepended with "consul-". (Consul -> Kubernetes sync) + # @type: string + k8sPrefix: null + + # List of k8s namespaces to sync the k8s services from. + # If a k8s namespace is not included in this list or is listed in `k8sDenyNamespaces`, + # services in that k8s namespace will not be synced even if they are explicitly + # annotated. Use `["*"]` to automatically allow all k8s namespaces. + # + # For example, `["namespace1", "namespace2"]` will only allow services in the k8s + # namespaces `namespace1` and `namespace2` to be synced and registered + # with Consul. All other k8s namespaces will be ignored. + # + # To deny all namespaces, set this to `[]`. + # + # Note: `k8sDenyNamespaces` takes precedence over values defined here. + # @type: array + k8sAllowNamespaces: ["*"] + + # List of k8s namespaces that should not have their + # services synced. This list takes precedence over `k8sAllowNamespaces`. + # `*` is not supported because then nothing would be allowed to sync. + # + # For example, if `k8sAllowNamespaces` is `["*"]` and `k8sDenyNamespaces` is + # `["namespace1", "namespace2"]`, then all k8s namespaces besides `namespace1` + # and `namespace2` will be synced. + # @type: array + k8sDenyNamespaces: ["kube-system", "kube-public"] + + # [DEPRECATED] Use k8sAllowNamespaces and k8sDenyNamespaces instead. For + # backwards compatibility, if both this and the allow/deny lists are set, + # the allow/deny lists will be ignored. + # k8sSourceNamespace is the Kubernetes namespace to watch for service + # changes and sync to Consul. If this is not set then it will default + # to all namespaces. + # @type: string + k8sSourceNamespace: null + + # [Enterprise Only] These settings manage the catalog sync's interaction with + # Consul namespaces (requires consul-ent v1.7+). + # Also, `global.enableConsulNamespaces` must be true. + consulNamespaces: + # Name of the Consul namespace to register all + # k8s services into. If the Consul namespace does not already exist, + # it will be created. This will be ignored if `mirroringK8S` is true. + consulDestinationNamespace: "default" + + # If true, k8s services will be registered into a Consul namespace + # of the same name as their k8s namespace, optionally prefixed if + # `mirroringK8SPrefix` is set below. If the Consul namespace does not + # already exist, it will be created. Turning this on overrides the + # `consulDestinationNamespace` setting. + # `addK8SNamespaceSuffix` may no longer be needed if enabling this option. + # If mirroring is enabled, avoid creating any Consul resources in the following + # Kubernetes namespaces, as Consul currently reserves these namespaces for + # system use: "system", "universal", "operator", "root". + mirroringK8S: true + + # If `mirroringK8S` is set to true, `mirroringK8SPrefix` allows each Consul namespace + # to be given a prefix. For example, if `mirroringK8SPrefix` is set to "k8s-", a + # service in the k8s `staging` namespace will be registered into the + # `k8s-staging` Consul namespace. + mirroringK8SPrefix: "" + + # Appends Kubernetes namespace suffix to + # each service name synced to Consul, separated by a dash. + # For example, for a service 'foo' in the default namespace, + # the sync process will create a Consul service named 'foo-default'. + # Set this flag to true to avoid registering services with the same name + # but in different namespaces as instances for the same Consul service. + # Namespace suffix is not added if 'annotationServiceName' is provided. + addK8SNamespaceSuffix: true + + # Service prefix which prepends itself + # to Kubernetes services registered within Consul + # For example, "k8s-" will register all services prepended with "k8s-". + # (Kubernetes -> Consul sync) + # consulPrefix is ignored when 'annotationServiceName' is provided. + # NOTE: Updating this property to a non-null value for an existing installation will result in deregistering + # of existing services in Consul and registering them with a new name. + # @type: string + consulPrefix: null + + # Optional tag that is applied to all of the Kubernetes services + # that are synced into Consul. If nothing is set, defaults to "k8s". + # (Kubernetes -> Consul sync) + # @type: string + k8sTag: null + + # Defines the Consul synthetic node that all services + # will be registered to. + # NOTE: Changing the node name and upgrading the Helm chart will leave + # all of the previously sync'd services registered with Consul and + # register them again under the new Consul node name. The out-of-date + # registrations will need to be explicitly removed. + consulNodeName: "k8s-sync" + + # Syncs services of the ClusterIP type, which may + # or may not be broadly accessible depending on your Kubernetes cluster. + # Set this to false to skip syncing ClusterIP services. + syncClusterIPServices: true + + # If true, LoadBalancer service endpoints instead of ingress addresses will be synced to Consul. + # If false, LoadBalancer endpoints are not synced to Consul. + syncLoadBalancerEndpoints: false + + ingress: + # Syncs the hostname from a Kubernetes Ingress resource to service registrations + # when a rule matched a service. Currently only supports host based routing and + # not path based routing. The only supported path on an ingress rule is "/". + # Set this to false to skip syncing Ingress services. + # + # Currently, port 80 is synced if there is not TLS entry for the hostname. Syncs the port + # 443 if there is a TLS entry that matches the hostname. + enabled: false + # Requires syncIngress to be `true`. syncs the LoadBalancer IP from a Kubernetes Ingress + # resource instead of the hostname to service registrations when a rule matched a service. + loadBalancerIPs: false + + # Configures the type of syncing that happens for NodePort + # services. The valid options are: ExternalOnly, InternalOnly, ExternalFirst. + # + # - ExternalOnly will only use a node's ExternalIP address for the sync + # - InternalOnly use's the node's InternalIP address + # - ExternalFirst will preferentially use the node's ExternalIP address, but + # if it doesn't exist, it will use the node's InternalIP address instead. + nodePortSyncType: ExternalFirst + + # Refers to a Kubernetes secret that you have created that contains + # an ACL token for your Consul cluster which allows the sync process the correct + # permissions. This is only needed if ACLs are managed manually within the Consul cluster, i.e. `global.acls.manageSystemACLs` is `false`. + aclSyncToken: + # The name of the Kubernetes secret that holds the acl sync token. + # @type: string + secretName: null + # The key within the Kubernetes secret that holds the acl sync token. + # @type: string + secretKey: null + + # This value defines [`nodeSelector`](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector) + # labels for catalog sync pod assignment, formatted as a multi-line string. + # + # Example: + # + # ```yaml + # nodeSelector: | + # beta.kubernetes.io/arch: amd64 + # ``` + # + # @type: string + nodeSelector: null + + # Affinity Settings + # This should be a multi-line string matching the affinity object + # @type: string + affinity: null + + # Toleration Settings + # This should be a multi-line string matching the Toleration array + # in a PodSpec. + # @type: string + tolerations: null + + serviceAccount: + # This value defines additional annotations for the mesh gateways' service account. This should be formatted as a + # multi-line string. + # + # ```yaml + # annotations: | + # "sample/annotation1": "foo" + # "sample/annotation2": "bar" + # ``` + # + # @type: string + annotations: null + + # The resource settings for sync catalog pods. + # @recurse: false + # @type: map + resources: + requests: + memory: "50Mi" + cpu: "50m" + limits: + memory: "50Mi" + cpu: "50m" + + # Override global log verbosity level. One of "debug", "info", "warn", or "error". + # @type: string + logLevel: "" + + # Override the default interval to perform syncing operations creating Consul services. + # @type: string + consulWriteInterval: null + + # Extra labels to attach to the sync catalog pods. This should be a YAML map. + # + # Example: + # + # ```yaml + # extraLabels: + # labelKey: label-value + # anotherLabelKey: another-label-value + # ``` + # + # @type: map + extraLabels: null + + # This value defines additional annotations for + # the catalog sync pods. This should be formatted as a multi-line string. + # + # ```yaml + # annotations: | + # "sample/annotation1": "foo" + # "sample/annotation2": "bar" + # ``` + # + # @type: string + annotations: null + +# Configures the automatic Connect sidecar injector. +connectInject: + # True if you want to enable connect injection. Set to "-" to inherit from + # global.enabled. + enabled: true + + # The number of deployment replicas. + replicas: 1 + + # Image for consul-k8s-control-plane that contains the injector. + # @type: string + image: null + + # If true, the injector will inject the + # Connect sidecar into all pods by default. Otherwise, pods must specify the + # [injection annotation](https://developer.hashicorp.com/consul/docs/k8s/connect#consul-hashicorp-com-connect-inject) + # to opt-in to Connect injection. If this is true, pods can use the same annotation + # to explicitly opt-out of injection. + default: false + + # Configures Transparent Proxy for Consul Service mesh services. + # Using this feature requires Consul 1.10.0-beta1+. + transparentProxy: + # If true, then all Consul Service mesh will run with transparent proxy enabled by default, + # i.e. we enforce that all traffic within the pod will go through the proxy. + # This value is overridable via the "consul.hashicorp.com/transparent-proxy" pod annotation. + defaultEnabled: true + + # If true, we will overwrite Kubernetes HTTP probes of the pod to point to the Envoy proxy instead. + # This setting is recommended because with traffic being enforced to go through the Envoy proxy, + # the probes on the pod will fail because kube-proxy doesn't have the right certificates + # to talk to Envoy. + # This value is also overridable via the "consul.hashicorp.com/transparent-proxy-overwrite-probes" annotation. + # Note: This value has no effect if transparent proxy is disabled on the pod. + defaultOverwriteProbes: true + + # This configures the [`PodDisruptionBudget`](https://kubernetes.io/docs/tasks/run-application/configure-pdb/) + # for the service mesh sidecar injector. + disruptionBudget: + # This will enable/disable registering a PodDisruptionBudget for the + # service mesh sidecar injector. If this is enabled, it will only register the budget so long as + # the service mesh is enabled. + enabled: true + + # The maximum number of unavailable pods. By default, this will be + # automatically computed based on the `connectInject.replicas` value to be `(n/2)-1`. + # If you need to set this to `0`, you will need to add a + # --set 'connectInject.disruptionBudget.maxUnavailable=0'` flag to the helm chart installation + # command because of a limitation in the Helm templating language. + # @type: integer + maxUnavailable: null + + # The minimum number of available pods. + # Takes precedence over maxUnavailable if set. + # @type: integer + minAvailable: null + + # Configuration settings for the Consul API Gateway integration. + apiGateway: + # Enables Consul on Kubernetes to manage the CRDs used for Gateway API. + # Setting this to true will install the CRDs used for the Gateway API when Consul on Kubernetes is installed. + # These CRDs can clash with existing Gateway API CRDs if they are already installed in your cluster. + # If this setting is false, you will need to install the Gateway API CRDs manually. + manageExternalCRDs: true + + # Enables Consul on Kubernets to manage only the non-standard CRDs used for Gateway API. If manageExternalCRDs is true + # then all CRDs will be installed; otherwise, if manageNonStandardCRDs is true then only TCPRoute, GatewayClassConfig and MeshService + # will be installed. + manageNonStandardCRDs: false + + # Configuration settings for the GatewayClass installed by Consul on Kubernetes. + managedGatewayClass: + # This value defines [`nodeSelector`](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector) + # labels for gateway pod assignment, formatted as a multi-line string. + # + # Example: + # + # ```yaml + # nodeSelector: | + # beta.kubernetes.io/arch: amd64 + # ``` + # + # @type: string + nodeSelector: null + + # Toleration settings for gateway pods created with the managed gateway class. + # This should be a multi-line string matching the + # [Tolerations](https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/) array in a Pod spec. + # + # @type: string + tolerations: null + + # This value defines the type of Service created for gateways (e.g. LoadBalancer, ClusterIP) + serviceType: LoadBalancer + + # Configuration settings for annotations to be copied from the Gateway to other child resources. + copyAnnotations: + # This value defines a list of annotations to be copied from the Gateway to the Service created, formatted as a multi-line string. + # + # Example: + # + # ```yaml + # service: + # annotations: | + # - external-dns.alpha.kubernetes.io/hostname + # ``` + # + # @type: string + service: null + + # Metrics settings for gateways created with this gateway class configuration. + metrics: + # This value enables or disables metrics collection on a gateway, overriding the global gateway metrics collection settings. + # @type: boolean + enabled: "-" + # This value sets the port to use for scraping gateway metrics via prometheus, defaults to 20200 if not set. Must be in the port + # range of 1024-65535. + # @type: int + port: null + # This value sets the path to use for scraping gateway metrics via prometheus, defaults to /metrics if not set. + # @type: string + path: null + + # The resource settings for Pods handling traffic for Gateway API. + # @recurse: false + # @type: map + resources: + requests: + memory: "100Mi" + cpu: "100m" + limits: + memory: "100Mi" + cpu: "100m" + + # This value defines the number of pods to deploy for each Gateway as well as a min and max number of pods for all Gateways + deployment: + defaultInstances: 1 + maxInstances: 1 + minInstances: 1 + + # The name of the OpenShift SecurityContextConstraints resource to use for Gateways. + # Only applicable if `global.openshift.enabled` is true. + # @type: string + openshiftSCCName: "restricted-v2" + + # This value defines the amount we will add to privileged container ports on gateways that use this class. + # This is useful if you don't want to give your containers extra permissions to run privileged ports. + # Example: The gateway listener is defined on port 80, but the underlying value of the port on the container + # will be the 80 + the number defined below. + mapPrivilegedContainerPorts: 0 + + # This value contains settings related to the gateway_resources_job that runs on helm install + resourceJob: + # The resource requests (CPU, memory, etc.) for the server-acl-init and server-acl-init-cleanup pods. + # This should be a YAML map corresponding to a Kubernetes + # [`ResourceRequirements``](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#resourcerequirements-v1-core) + # object. + # + # Example: + # + # ```yaml + # resources: + # requests: + # memory: '200Mi' + # cpu: '100m' + # limits: + # memory: '200Mi' + # cpu: '100m' + # ``` + # + # @recurse: false + # @type: map + resources: + requests: + memory: "50Mi" + cpu: "50m" + limits: + memory: "50Mi" + cpu: "50m" + + # Configuration for the ServiceAccount created for the api-gateway component + serviceAccount: + # This value defines additional annotations for the client service account. This should be formatted as a multi-line + # string. + # + # ```yaml + # annotations: | + # "sample/annotation1": "foo" + # "sample/annotation2": "bar" + # ``` + # + # @type: string + annotations: null + + # Configures consul-cni plugin for Consul Service mesh services + cni: + # If true, then all traffic redirection setup uses the consul-cni plugin. + # Requires connectInject.enabled to also be true. + # @type: boolean + enabled: false + + # Log level for the installer and plugin. Overrides global.logLevel + # @type: string + logLevel: null + + # Set the namespace to install the CNI plugin into. Overrides global namespace settings for CNI resources. + # Ex: "kube-system" + # @type: string + namespace: null + + # Location on the kubernetes node where the CNI plugin is installed. Shoud be the absolute path and start with a '/' + # Example on GKE: + # + # ```yaml + # cniBinDir: "/home/kubernetes/bin" + # ``` + # @type: string + cniBinDir: "/opt/cni/bin" + + # Location on the kubernetes node of all CNI configuration. Should be the absolute path and start with a '/' + # @type: string + cniNetDir: "/etc/cni/net.d" + + # If multus CNI plugin is enabled with consul-cni. When enabled, consul-cni will not be installed as a chained + # CNI plugin. Instead, a NetworkAttachementDefinition CustomResourceDefinition (CRD) will be created in the helm + # release namespace. Following multus plugin standards, an annotation is required in order for the consul-cni plugin + # to be executed and for your service to be added to the Consul Service Mesh. + # + # Add the annotation `'k8s.v1.cni.cncf.io/networks': '[{ "name":"consul-cni","namespace": "consul" }]'` to your pod + # to use the default installed NetworkAttachementDefinition CRD. + # + # Please refer to the [Multus Quickstart Guide](https://github.com/k8snetworkplumbingwg/multus-cni/blob/master/docs/quickstart.md) + # for more information about using multus. + # @type: string + multus: false + + # The resource settings for CNI installer daemonset. + # @recurse: false + # @type: map + resources: + requests: + memory: "75Mi" + cpu: "75m" + limits: + memory: "100Mi" + cpu: "100m" + + # Resource quotas for running the daemonset as system critical pods + resourceQuota: + pods: 5000 + + # The security context for the CNI installer daemonset. This should be a YAML map corresponding to a + # Kubernetes [SecurityContext](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) object. + # By default, servers will run as root, with user ID `0` and group ID `0`. + # Note: if running on OpenShift, this setting is ignored because the user and group are set automatically + # by the OpenShift platform. + # @type: map + # @recurse: false + securityContext: + runAsNonRoot: false + runAsGroup: 0 + runAsUser: 0 + + # updateStrategy for the CNI installer DaemonSet. + # Refer to the Kubernetes [Daemonset upgrade strategy](https://kubernetes.io/docs/tasks/manage-daemon/update-daemon-set/#daemonset-update-strategy) + # documentation. + # This should be a multi-line string mapping directly to the updateStrategy + # + # Example: + # + # ```yaml + # updateStrategy: | + # rollingUpdate: + # maxUnavailable: 5 + # type: RollingUpdate + # ``` + # + # @type: string + updateStrategy: null + + consulNode: + # meta specifies an arbitrary metadata key/value pair to associate with the node. + # + # Example: + # + # ```yaml + # meta: + # cluster: test-cluster + # persistent: true + # ``` + # + # @type: map + meta: null + + # Configures metrics for Consul service mesh services. All values are overridable + # via annotations on a per-pod basis. + metrics: + # If true, the connect-injector will automatically + # add prometheus annotations to connect-injected pods. It will also + # add a listener on the Envoy sidecar to expose metrics. The exposed + # metrics will depend on whether metrics merging is enabled: + # - If metrics merging is enabled: + # the consul-dataplane will run a merged metrics server + # combining Envoy sidecar and Connect service metrics, + # i.e. if your service exposes its own Prometheus metrics. + # - If metrics merging is disabled: + # the listener will just expose Envoy sidecar metrics. + # This will inherit from `global.metrics.enabled`. + defaultEnabled: "-" + # Configures the consul-dataplane to run a merged metrics server + # to combine and serve both Envoy and Connect service metrics. + # This feature is available only in Consul v1.10.0 or greater. + defaultEnableMerging: false + # Configures the port at which the consul-dataplane will listen on to return + # combined metrics. This port only needs to be changed if it conflicts with + # the application's ports. + defaultMergedMetricsPort: 20100 + # Configures the port Prometheus will scrape metrics from, by configuring + # the Pod annotation `prometheus.io/port` and the corresponding listener in + # the Envoy sidecar. + # NOTE: This is *not* the port that your application exposes metrics on. + # That can be configured with the + # `consul.hashicorp.com/service-metrics-port` annotation. + defaultPrometheusScrapePort: 20200 + # Configures the path Prometheus will scrape metrics from, by configuring the pod + # annotation `prometheus.io/path` and the corresponding handler in the Envoy + # sidecar. + # NOTE: This is *not* the path that your application exposes metrics on. + # That can be configured with the + # `consul.hashicorp.com/service-metrics-path` annotation. + defaultPrometheusScrapePath: "/metrics" + + # Used to pass arguments to the injected envoy sidecar. + # Valid arguments to pass to envoy can be found here: https://www.envoyproxy.io/docs/envoy/latest/operations/cli + # e.g "--log-level debug --disable-hot-restart" + # @type: string + envoyExtraArgs: null + + # Optional priorityClassName. + priorityClassName: "" + + # Extra labels to attach to the connect inject pods. This should be a YAML map. + # + # Example: + # + # ```yaml + # extraLabels: + # labelKey: label-value + # anotherLabelKey: another-label-value + # ``` + # + # @type: map + extraLabels: null + + # This value defines additional annotations for + # connect inject pods. This should be formatted as a multi-line string. + # + # ```yaml + # annotations: | + # "sample/annotation1": "foo" + # "sample/annotation2": "bar" + # ``` + # + # @type: string + annotations: null + + # The Docker image for Consul to use when performing Connect injection. + # Defaults to global.image. + # @type: string + imageConsul: null + + # Sets the `logLevel` for the `consul-dataplane` sidecar and the `consul-connect-inject-init` container. When set, this value overrides the global log verbosity level. One of "debug", "info", "warn", or "error". + # @type: string + logLevel: "" + + serviceAccount: + # This value defines additional annotations for the injector service account. This should be formatted as a + # multi-line string. + # + # ```yaml + # annotations: | + # "sample/annotation1": "foo" + # "sample/annotation2": "bar" + # ``` + # + # @type: string + annotations: null + + # The resource settings for connect inject pods. The defaults, are optimized for getting started worklows on developer deployments. The settings should be tweaked for production deployments. + # @type: map + resources: + requests: + # Recommended production default: 500Mi + # @type: string + memory: "200Mi" + # Recommended production default: 250m + # @type: string + cpu: "50m" + limits: + # Recommended production default: 500Mi + # @type: string + memory: "200Mi" + # Recommended production default: 250m + # @type: string + cpu: "50m" + + # Sets the failurePolicy for the mutating webhook. By default this will cause pods not part of the consul installation to fail scheduling while the webhook + # is offline. This prevents a pod from skipping mutation if the webhook were to be momentarily offline. + # Once the webhook is back online the pod will be scheduled. + # In some environments such as Kind this may have an undesirable effect as it may prevent volume provisioner pods from running + # which can lead to hangs. In these environments it is recommend to use "Ignore" instead. + # This setting can be safely disabled by setting to "Ignore". + failurePolicy: "Fail" + + # Selector for restricting the webhook to only specific namespaces. + # Use with `connectInject.default: true` to automatically inject all pods in namespaces that match the selector. This should be set to a multiline string. + # Refer to https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#matching-requests-namespaceselector + # for more details. + # + # By default, we exclude kube-system since usually users won't + # want those pods injected and local-path-storage and openebs so that + # Kind (Kubernetes In Docker) and [OpenEBS](https://openebs.io/) respectively can provision Pods used to create PVCs. + # Note that this exclusion is only supported in Kubernetes v1.21.1+. + # + # Example: + # + # ```yaml + # namespaceSelector: | + # matchLabels: + # namespace-label: label-value + # ``` + # @type: string + namespaceSelector: | + matchExpressions: + - key: "kubernetes.io/metadata.name" + operator: "NotIn" + values: ["kube-system","local-path-storage","openebs"] + + # List of k8s namespaces to allow Connect sidecar + # injection in. If a k8s namespace is not included or is listed in `k8sDenyNamespaces`, + # pods in that k8s namespace will not be injected even if they are explicitly + # annotated. Use `["*"]` to automatically allow all k8s namespaces. + # + # For example, `["namespace1", "namespace2"]` will only allow pods in the k8s + # namespaces `namespace1` and `namespace2` to have Consul service mesh sidecars injected + # and registered with Consul. All other k8s namespaces will be ignored. + # + # To deny all namespaces, set this to `[]`. + # + # Note: `k8sDenyNamespaces` takes precedence over values defined here and + # `namespaceSelector` takes precedence over both since it is applied first. + # `kube-system` and `kube-public` are never injected, even if included here. + # @type: array + k8sAllowNamespaces: ["*"] + + # List of k8s namespaces that should not allow Connect + # sidecar injection. This list takes precedence over `k8sAllowNamespaces`. + # `*` is not supported because then nothing would be allowed to be injected. + # + # For example, if `k8sAllowNamespaces` is `["*"]` and k8sDenyNamespaces is + # `["namespace1", "namespace2"]`, then all k8s namespaces besides "namespace1" + # and "namespace2" will be available for injection. + # + # Note: `namespaceSelector` takes precedence over this since it is applied first. + # `kube-system` and `kube-public` are never injected. + # @type: array + k8sDenyNamespaces: [] + + # [Enterprise Only] These settings manage the connect injector's interaction with + # Consul namespaces (requires consul-ent v1.7+). + # Also, `global.enableConsulNamespaces` must be true. + consulNamespaces: + # Name of the Consul namespace to register all + # k8s pods into. If the Consul namespace does not already exist, + # it will be created. This will be ignored if `mirroringK8S` is true. + consulDestinationNamespace: "default" + + # Causes k8s pods to be registered into a Consul namespace + # of the same name as their k8s namespace, optionally prefixed if + # `mirroringK8SPrefix` is set below. If the Consul namespace does not + # already exist, it will be created. Turning this on overrides the + # `consulDestinationNamespace` setting. If mirroring is enabled, avoid creating any Consul + # resources in the following Kubernetes namespaces, as Consul currently reserves these + # namespaces for system use: "system", "universal", "operator", "root". + mirroringK8S: true + + # If `mirroringK8S` is set to true, `mirroringK8SPrefix` allows each Consul namespace + # to be given a prefix. For example, if `mirroringK8SPrefix` is set to "k8s-", a + # pod in the k8s `staging` namespace will be registered into the + # `k8s-staging` Consul namespace. + mirroringK8SPrefix: "" + + # Selector labels for connectInject pod assignment, formatted as a multi-line string. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector + # + # Example: + # + # ```yaml + # nodeSelector: | + # beta.kubernetes.io/arch: amd64 + # ``` + # @type: string + nodeSelector: null + + # Affinity Settings + # This should be a multi-line string matching the affinity object + # @type: string + affinity: null + + # Toleration Settings + # This should be a multi-line string matching the Toleration array + # in a PodSpec. + # @type: string + tolerations: null + + # Query that defines which Service Accounts + # can authenticate to Consul and receive an ACL token during Connect injection. + # The default setting, i.e. serviceaccount.name!=default, prevents the + # 'default' Service Account from logging in. + # If set to an empty string all service accounts can log in. + # This only has effect if ACLs are enabled. + # + # Refer to Auth methods [Binding rules](https://developer.hashicorp.com/consul/docs/security/acl/auth-methods#binding-rules) + # and [Trusted identiy attributes](https://developer.hashicorp.com/consul/docs/security/acl/auth-methods/kubernetes#trusted-identity-attributes) + # for more details. + # Requires Consul >= v1.5. + aclBindingRuleSelector: "serviceaccount.name!=default" + + # If you are not using global.acls.manageSystemACLs and instead manually setting up an + # auth method for Connect inject, set this to the name of your auth method. + overrideAuthMethodName: "" + + # Refers to a Kubernetes secret that you have created that contains + # an ACL token for your Consul cluster which allows the Connect injector the correct + # permissions. This is only needed if Consul namespaces [Enterprise Only] and ACLs + # are enabled on the Consul cluster and you are not setting + # `global.acls.manageSystemACLs` to `true`. + # This token needs to have `operator = "write"` privileges to be able to + # create Consul namespaces. + aclInjectToken: + # The name of the Vault secret that holds the ACL inject token. + # @type: string + secretName: null + # The key within the Vault secret that holds the ACL inject token. + # @type: string + secretKey: null + + sidecarProxy: + # The number of worker threads to be used by the Envoy proxy. + # By default the threading model of Envoy will use one thread per CPU core per envoy proxy. This + # leads to unnecessary thread and memory usage and leaves unnecessary idle connections open. It is + # advised to keep this number low for sidecars and high for edge proxies. + # This will control the `--concurrency` flag to Envoy. + # For additional information, refer to https://blog.envoyproxy.io/envoy-threading-model-a8d44b922310 + # + # This setting can be overridden on a per-pod basis via this annotation: + # - `consul.hashicorp.com/consul-envoy-proxy-concurrency` + # @type: string + concurrency: 2 + + # Set default resources for sidecar proxy. If null, that resource won't + # be set. + # These settings can be overridden on a per-pod basis via these annotations: + # + # - `consul.hashicorp.com/sidecar-proxy-cpu-limit` + # - `consul.hashicorp.com/sidecar-proxy-cpu-request` + # - `consul.hashicorp.com/sidecar-proxy-memory-limit` + # - `consul.hashicorp.com/sidecar-proxy-memory-request` + # @type: map + resources: + requests: + # Recommended production default: 100Mi + # @type: string + memory: null + # Recommended production default: 100m + # @type: string + cpu: null + limits: + # Recommended production default: 100Mi + # @type: string + memory: null + # Recommended production default: 100m + # @type: string + cpu: null + # Set default lifecycle management configuration for sidecar proxy. + # These settings can be overridden on a per-pod basis via these annotations: + # + # - `consul.hashicorp.com/enable-sidecar-proxy-lifecycle` + # - `consul.hashicorp.com/enable-sidecar-proxy-shutdown-drain-listeners` + # - `consul.hashicorp.com/sidecar-proxy-lifecycle-shutdown-grace-period-seconds` + # - `consul.hashicorp.com/sidecar-proxy-lifecycle-startup-grace-period-seconds` + # - `consul.hashicorp.com/sidecar-proxy-lifecycle-graceful-port` + # - `consul.hashicorp.com/sidecar-proxy-lifecycle-graceful-shutdown-path` + # - `consul.hashicorp.com/sidecar-proxy-lifecycle-graceful-startup-path` + # @type: map + lifecycle: + # @type: boolean + defaultEnabled: true + # @type: boolean + defaultEnableShutdownDrainListeners: true + # @type: integer + defaultShutdownGracePeriodSeconds: 30 + # @type: integer + defaultStartupGracePeriodSeconds: 0 + # @type: integer + defaultGracefulPort: 20600 + # @type: string + defaultGracefulShutdownPath: "/graceful_shutdown" + # @type: string + defaultGracefulStartupPath: "/graceful_startup" + + # Configures how long the k8s startup probe will wait before the proxy is considered to be unhealthy and the container is restarted. + # A value of zero disables the probe. + defaultStartupFailureSeconds: 0 + # Configures how long the k8s liveness probe will wait before the proxy is considered to be unhealthy and the container is restarted. + # A value of zero disables the probe. + defaultLivenessFailureSeconds: 0 + + # The resource settings for the Connect injected init container. If null, the resources + # won't be set for the initContainer. The defaults are optimized for developer instances of + # Kubernetes, however they should be tweaked with the recommended defaults as shown below to speed up service registration times. + # @type: map + initContainer: + resources: + requests: + # Recommended production default: 150Mi + # @type: string + memory: "25Mi" + # Recommended production default: 250m + # @type: string + cpu: "50m" + limits: + # Recommended production default: 150Mi + # @type: string + memory: "150Mi" + # Recommended production default: 500m + # @type: string + cpu: null + +# [Mesh Gateways](https://developer.hashicorp.com/consul/docs/connect/gateways/mesh-gateway) enable Consul Connect to work across Consul datacenters. +meshGateway: + # If [mesh gateways](https://developer.hashicorp.com/consul/docs/connect/gateways/mesh-gateway) are enabled, a Deployment will be created that runs + # gateways and Consul service mesh will be configured to use gateways. + # This setting is required for [Cluster Peering](https://developer.hashicorp.com/consul/docs/connect/cluster-peering/k8s). + # Requirements: consul 1.6.0+ if using `global.acls.manageSystemACLs``. + enabled: false + + # Override global log verbosity level for mesh-gateway-deployment pods. One of "trace", "debug", "info", "warn", or "error". + # @type: string + logLevel: "" + + # Number of replicas for the Deployment. + replicas: 1 + + # What gets registered as WAN address for the gateway. + wanAddress: + # source configures where to retrieve the WAN address (and possibly port) + # for the mesh gateway from. + # Can be set to either: `Service`, `NodeIP`, `NodeName` or `Static`. + # + # - `Service` - Determine the address based on the service type. + # + # - If `service.type=LoadBalancer` use the external IP or hostname of + # the service. Use the port set by `service.port`. + # + # - If `service.type=NodePort` use the Node IP. The port will be set to + # `service.nodePort` so `service.nodePort` cannot be null. + # + # - If `service.type=ClusterIP` use the `ClusterIP`. The port will be set to + # `service.port`. + # + # - `service.type=ExternalName` is not supported. + # + # - `NodeIP` - The node IP as provided by the Kubernetes downward API. + # + # - `NodeName` - The name of the node as provided by the Kubernetes downward + # API. This is useful if the node names are DNS entries that + # are routable from other datacenters. + # + # - `Static` - Use the address hardcoded in `meshGateway.wanAddress.static`. + source: Service + + # Port that gets registered for WAN traffic. + # If source is set to "Service" then this setting will have no effect. + # Refer to the documentation for source as to which port will be used in that + # case. + port: 443 + + # If source is set to "Static" then this value will be used as the WAN + # address of the mesh gateways. This is useful if you've configured a + # DNS entry to point to your mesh gateways. + static: "" + + # The service option configures the Service that fronts the Gateway Deployment. + service: + # Type of service, ex. LoadBalancer, ClusterIP. + type: LoadBalancer + + # Port that the service will be exposed on. + # The targetPort will be set to meshGateway.containerPort. + port: 443 + + # Optionally set the nodePort value of the service if using a NodePort service. + # If not set and using a NodePort service, Kubernetes will automatically assign + # a port. + # @type: integer + nodePort: null + + # Annotations to apply to the mesh gateway service. + # + # Example: + # + # ```yaml + # annotations: | + # 'annotation-key': annotation-value + # ``` + # @type: string + annotations: null + + # Optional YAML string that will be appended to the Service spec. + # @type: string + additionalSpec: null + + # If set to true, gateway Pods will run on the host network. + hostNetwork: false + + # dnsPolicy to use. + # @type: string + dnsPolicy: null + + # Consul service name for the mesh gateways. + # Cannot be set to anything other than "mesh-gateway" if + # global.acls.manageSystemACLs is true since the ACL token + # generated is only for the name 'mesh-gateway'. + consulServiceName: "mesh-gateway" + + # Port that the gateway will run on inside the container. + containerPort: 8443 + + # Optional hostPort for the gateway to be exposed on. + # This can be used with wanAddress.port and wanAddress.useNodeIP + # to expose the gateways directly from the node. + # If hostNetwork is true, this must be null or set to the same port as + # containerPort. + # NOTE: Cannot set to 8500 or 8502 because those are reserved for the Consul + # agent. + # @type: integer + hostPort: null + + serviceAccount: + # This value defines additional annotations for the mesh gateways' service account. This should be formatted as a + # multi-line string. + # + # ```yaml + # annotations: | + # "sample/annotation1": "foo" + # "sample/annotation2": "bar" + # ``` + # + # @type: string + annotations: null + + # The resource settings for mesh gateway pods. + # NOTE: The use of a YAML string is deprecated. Instead, set directly as a + # YAML map. + # @recurse: false + # @type: map + resources: + requests: + memory: "100Mi" + cpu: "100m" + limits: + memory: "100Mi" + cpu: "100m" + + # The resource settings for the `service-init` init container. + # @recurse: false + # @type: map + initServiceInitContainer: + resources: + requests: + memory: "50Mi" + cpu: "50m" + limits: + memory: "50Mi" + cpu: "50m" + + # This value defines the [affinity](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity) + # for mesh gateway pods. It defaults to `null` thereby allowing multiple gateway pods on each node. But if one would prefer + # a mode which minimizes risk of the cluster becoming unusable if a node is lost, set this value + # to the value in the example below. + # + # Example: + # + # ```yaml + # affinity: | + # podAntiAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # - labelSelector: + # matchLabels: + # app: {{ template "consul.name" . }} + # release: "{{ .Release.Name }}" + # component: mesh-gateway + # topologyKey: kubernetes.io/hostname + # ``` + # @type: string + affinity: null + + # Optional YAML string to specify tolerations. + # @type: string + tolerations: null + + # Pod topology spread constraints for mesh gateway pods. + # This should be a multi-line YAML string matching the + # [`topologySpreadConstraints`](https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/) + # array in a Pod Spec. + # + # This requires K8S >= 1.18 (beta) or 1.19 (stable). + # + # Example: + # + # ```yaml + # topologySpreadConstraints: | + # - maxSkew: 1 + # topologyKey: topology.kubernetes.io/zone + # whenUnsatisfiable: DoNotSchedule + # labelSelector: + # matchLabels: + # app: {{ template "consul.name" . }} + # release: "{{ .Release.Name }}" + # component: mesh-gateway + # ``` + topologySpreadConstraints: "" + + # Optional YAML string to specify a nodeSelector config. + # @type: string + nodeSelector: null + + # Optional priorityClassName. + priorityClassName: "" + + # Annotations to apply to the mesh gateway deployment. + # + # Example: + # + # ```yaml + # annotations: | + # 'annotation-key': annotation-value + # ``` + # @type: string + annotations: null + +# Configuration options for ingress gateways. Default values for all +# ingress gateways are defined in `ingressGateways.defaults`. Any of +# these values may be overridden in `ingressGateways.gateways` for a +# specific gateway with the exception of annotations. Annotations will +# include both the default annotations and any additional ones defined +# for a specific gateway. +# Requirements: consul >= 1.8.0 +ingressGateways: + # Enable ingress gateway deployment. Requires `connectInject.enabled=true`. + enabled: false + + # Override global log verbosity level for ingress-gateways-deployment pods. One of "trace", "debug", "info", "warn", or "error". + # @type: string + logLevel: "" + + # Defaults sets default values for all gateway fields. With the exception + # of annotations, defining any of these values in the `gateways` list + # will override the default values provided here. Annotations will + # include both the default annotations and any additional ones defined + # for a specific gateway. + defaults: + # Number of replicas for each ingress gateway defined. + replicas: 1 + + # The service options configure the Service that fronts the gateway Deployment. + service: + # Type of service: LoadBalancer, ClusterIP or NodePort. If using NodePort service + # type, you must set the desired nodePorts in the `ports` setting below. + type: ClusterIP + + # Ports that will be exposed on the service and gateway container. Any + # ports defined as ingress listeners on the gateway's Consul configuration + # entry should be included here. The first port will be used as part of + # the Consul service registration for the gateway and be listed in its + # SRV record. If using a NodePort service type, you must specify the + # desired nodePort for each exposed port. + # @type: array + # @default: [{port: 8080, port: 8443}] + # @recurse: false + ports: + - port: 8080 + nodePort: null + - port: 8443 + nodePort: null + + # Annotations to apply to the ingress gateway service. Annotations defined + # here will be applied to all ingress gateway services in addition to any + # service annotations defined for a specific gateway in `ingressGateways.gateways`. + # + # Example: + # + # ```yaml + # annotations: | + # 'annotation-key': annotation-value + # ``` + # @type: string + annotations: null + + # Optional YAML string that will be appended to the Service spec. + # @type: string + additionalSpec: null + + serviceAccount: + # This value defines additional annotations for the ingress gateways' service account. This should be formatted + # as a multi-line string. + # + # ```yaml + # annotations: | + # "sample/annotation1": "foo" + # "sample/annotation2": "bar" + # ``` + # + # @type: string + annotations: null + + # Resource limits for all ingress gateway pods + # @recurse: false + # @type: map + resources: + requests: + memory: "100Mi" + cpu: "100m" + limits: + memory: "100Mi" + cpu: "100m" + + # This value defines the [affinity](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity) + # for ingress gateway pods. It defaults to `null` thereby allowing multiple gateway pods on each node. But if one would prefer + # a mode which minimizes risk of the cluster becoming unusable if a node is lost, set this value + # to the value in the example below. + # + # Example: + # + # ```yaml + # affinity: | + # podAntiAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # - labelSelector: + # matchLabels: + # app: {{ template "consul.name" . }} + # release: "{{ .Release.Name }}" + # component: ingress-gateway + # topologyKey: kubernetes.io/hostname + # ``` + # @type: string + affinity: null + + # Optional YAML string to specify tolerations. + # @type: string + tolerations: null + + # Pod topology spread constraints for ingress gateway pods. + # This should be a multi-line YAML string matching the + # [`topologySpreadConstraints`](https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/) + # array in a Pod Spec. + # + # This requires K8S >= 1.18 (beta) or 1.19 (stable). + # + # Example: + # + # ```yaml + # topologySpreadConstraints: | + # - maxSkew: 1 + # topologyKey: topology.kubernetes.io/zone + # whenUnsatisfiable: DoNotSchedule + # labelSelector: + # matchLabels: + # app: {{ template "consul.name" . }} + # release: "{{ .Release.Name }}" + # component: ingress-gateway + # ``` + topologySpreadConstraints: "" + + # Optional YAML string to specify a nodeSelector config. + # @type: string + nodeSelector: null + + # Optional priorityClassName. + priorityClassName: "" + + # Amount of seconds to wait for graceful termination before killing the pod. + terminationGracePeriodSeconds: 10 + + # Annotations to apply to the ingress gateway deployment. Annotations defined + # here will be applied to all ingress gateway deployments in addition to any + # annotations defined for a specific gateway in `ingressGateways.gateways`. + # + # Example: + # + # ```yaml + # annotations: | + # "annotation-key": 'annotation-value' + # ``` + # @type: string + annotations: null + + # [Enterprise Only] `consulNamespace` defines the Consul namespace to register + # the gateway into. Requires `global.enableConsulNamespaces` to be true and + # Consul Enterprise v1.7+ with a valid Consul Enterprise license. + # Note: The Consul namespace MUST exist before the gateway is deployed. + consulNamespace: "default" + + # Gateways is a list of gateway objects. The only required field for + # each is `name`, though they can also contain any of the fields in + # `defaults`. You must provide a unique name for each ingress gateway. These names + # must be unique across different namespaces. + # Values defined here override the defaults, except in the case of annotations where both will be applied. + # @type: array + gateways: + - name: ingress-gateway + +# Configuration options for terminating gateways. Default values for all +# terminating gateways are defined in `terminatingGateways.defaults`. Any of +# these values may be overridden in `terminatingGateways.gateways` for a +# specific gateway with the exception of annotations. Annotations will +# include both the default annotations and any additional ones defined +# for a specific gateway. +# Requirements: consul >= 1.8.0 +terminatingGateways: + # Enable terminating gateway deployment. Requires `connectInject.enabled=true`. + enabled: false + + # Override global log verbosity level. One of "trace", "debug", "info", "warn", or "error". + # @type: string + logLevel: "" + + # Defaults sets default values for all gateway fields. With the exception + # of annotations, defining any of these values in the `gateways` list + # will override the default values provided here. Annotations will + # include both the default annotations and any additional ones defined + # for a specific gateway. + defaults: + # Number of replicas for each terminating gateway defined. + replicas: 1 + + # A list of extra volumes to mount. These will be exposed to Consul in the path `/consul/userconfig//`. + # + # Example: + # + # ```yaml + # extraVolumes: + # - type: secret + # name: my-secret + # items: # optional items array + # - key: key + # path: path # secret will now mount to /consul/userconfig/my-secret/path + # ``` + # @type: array + extraVolumes: [] + + # Resource limits for all terminating gateway pods + # @recurse: false + # @type: map + resources: + requests: + memory: "100Mi" + cpu: "100m" + limits: + memory: "100Mi" + cpu: "100m" + + # This value defines the [affinity](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity) + # for terminating gateway pods. It defaults to `null` thereby allowing multiple gateway pods on each node. But if one would prefer + # a mode which minimizes risk of the cluster becoming unusable if a node is lost, set this value + # to the value in the example below. + # + # Example: + # + # ```yaml + # affinity: | + # podAntiAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # - labelSelector: + # matchLabels: + # app: {{ template "consul.name" . }} + # release: "{{ .Release.Name }}" + # component: terminating-gateway + # topologyKey: kubernetes.io/hostname + # ``` + # @type: string + affinity: null + + # Optional YAML string to specify tolerations. + # @type: string + tolerations: null + + # Pod topology spread constraints for terminating gateway pods. + # This should be a multi-line YAML string matching the + # [`topologySpreadConstraints`](https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/) + # array in a Pod Spec. + # + # This requires K8S >= 1.18 (beta) or 1.19 (stable). + # + # Example: + # + # ```yaml + # topologySpreadConstraints: | + # - maxSkew: 1 + # topologyKey: topology.kubernetes.io/zone + # whenUnsatisfiable: DoNotSchedule + # labelSelector: + # matchLabels: + # app: {{ template "consul.name" . }} + # release: "{{ .Release.Name }}" + # component: terminating-gateway + # ``` + topologySpreadConstraints: "" + + # Optional YAML string to specify a nodeSelector config. + # @type: string + nodeSelector: null + + # Optional priorityClassName. + # @type: string + priorityClassName: "" + + # Annotations to apply to the terminating gateway deployment. Annotations defined + # here will be applied to all terminating gateway deployments in addition to any + # annotations defined for a specific gateway in `terminatingGateways.gateways`. + # + # Example: + # + # ```yaml + # annotations: | + # 'annotation-key': annotation-value + # ``` + # @type: string + annotations: null + + serviceAccount: + # This value defines additional annotations for the terminating gateways' service account. This should be + # formatted as a multi-line string. + # + # ```yaml + # annotations: | + # "sample/annotation1": "foo" + # "sample/annotation2": "bar" + # ``` + # + # @type: string + annotations: null + + # [Enterprise Only] `consulNamespace` defines the Consul namespace to register + # the gateway into. Requires `global.enableConsulNamespaces` to be true and + # Consul Enterprise v1.7+ with a valid Consul Enterprise license. + # Note: The Consul namespace MUST exist before the gateway is deployed. + consulNamespace: "default" + + # Gateways is a list of gateway objects. The only required field for + # each is `name`, though they can also contain any of the fields in + # `defaults`. Values defined here override the defaults except in the + # case of annotations where both will be applied. + # @type: array + gateways: + - name: terminating-gateway + +# Configuration settings for the webhook-cert-manager +# `webhook-cert-manager` ensures that cert bundles are up to date for the mutating webhook. +webhookCertManager: + # Toleration Settings + # This should be a multi-line string matching the Toleration array + # in a PodSpec. + # @type: string + tolerations: null + + # This value defines [`nodeSelector`](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector) + # labels for the webhook-cert-manager pod assignment, formatted as a multi-line string. + # + # Example: + # + # ```yaml + # nodeSelector: | + # beta.kubernetes.io/arch: amd64 + # ``` + # + # @type: string + nodeSelector: null + + # The resource requests (CPU, memory, etc.) for the server-acl-init and server-acl-init-cleanup pods. + # This should be a YAML map corresponding to a Kubernetes + # [`ResourceRequirements``](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#resourcerequirements-v1-core) + # object. + # + # Example: + # + # ```yaml + # resources: + # requests: + # memory: '200Mi' + # cpu: '100m' + # limits: + # memory: '200Mi' + # cpu: '100m' + # ``` + # + # @recurse: false + # @type: map + resources: + requests: + memory: "50Mi" + cpu: "100m" + limits: + memory: "50Mi" + cpu: "100m" + +# Configures a demo Prometheus installation. +prometheus: + # When true, the Helm chart will install a demo Prometheus server instance + # alongside Consul. + enabled: false + +# Control whether a test Pod manifest is generated when running helm template. +# When using helm install, the test Pod is not submitted to the cluster so this +# is only useful when running helm template. +tests: + enabled: true + +telemetryCollector: + # Enables the consul-telemetry-collector deployment + # @type: boolean + enabled: false + + # Override global log verbosity level. One of "trace", "debug", "info", "warn", or "error". + # @type: string + logLevel: "" + + # The name of the Docker image (including any tag) for the containers running + # the consul-telemetry-collector + # @type: string + image: "hashicorp/consul-telemetry-collector:0.0.2" + + # The resource settings for consul-telemetry-collector pods. + # @recurse: false + # @type: map + resources: + requests: + memory: "512Mi" + cpu: "1000m" + limits: + memory: "512Mi" + cpu: "1000m" + + # This value sets the number of consul-telemetry-collector replicas to deploy. + replicas: 1 + + # This value defines additional configuration for the telemetry collector. It should be formatted as a multi-line + # json blob string + # + # ```yaml + # customExporterConfig: | + # {"http_collector_endpoint": "other-otel-collector"} + # ``` + # + # @type: string + customExporterConfig: null + + service: + # This value defines additional annotations for the telemetry-collector's service account. This should be formatted as a multi-line + # string. + # + # ```yaml + # annotations: | + # "sample/annotation1": "foo" + # "sample/annotation2": "bar" + # ``` + # + # @type: string + annotations: null + + serviceAccount: + # This value defines additional annotations for the telemetry-collector's service account. This should be formatted + # as a multi-line string. + # + # ```yaml + # annotations: | + # "sample/annotation1": "foo" + # "sample/annotation2": "bar" + # ``` + # + # @type: string + annotations: null + + cloud: + # The resource id of the HCP Consul Central cluster to push metrics for. Eg: + # `organization/27109cd4-a309-4bf3-9986-e1d071914b18/project/fcef6c24-259d-4510-bb8d-1d812e120e34/hashicorp.consul.global-network-manager.cluster/consul-cluster` + # + # This is used for HCP Consul Central-linked or HCP Consul Dedicated clusters where global.cloud.resourceId is unset. For example, when using externalServers + # with HCP Consul Dedicated clusters or HCP Consul Central-linked clusters in a different admin partition. + # + # If global.cloud.resourceId is set, this should either be unset (defaulting to global.cloud.resourceId) or be the same as global.cloud.resourceId. + # + # @default: global.cloud.resourceId + resourceId: + # The name of the Kubernetes secret that holds the resource id. + # @type: string + secretName: null + # The key within the Kubernetes secret that holds the resource id. + # @type: string + secretKey: null + + # The client id portion of a [service principal](https://developer.hashicorp.com/hcp/docs/hcp/admin/iam/service-principals#service-principals) with authorization to push metrics to HCP + # + # This is set in two scenarios: + # - the service principal in global.cloud is unset + # - the HCP UI provides a service principal with more narrowly scoped permissions that the service principal used in global.cloud + # + # @default: global.cloud.clientId + clientId: + # The name of the Kubernetes secret that holds the client id. + # @type: string + secretName: null + # The key within the Kubernetes secret that holds the client id. + # @type: string + secretKey: null + + # The client secret portion of a [service principal](https://developer.hashicorp.com/hcp/docs/hcp/admin/iam/service-principals#service-principals) with authorization to push metrics to HCP. + # + # This is set in two scenarios: + # - the service principal in global.cloud is unset + # - the HCP UI provides a service principal with more narrowly scoped permissions that the service principal used in global.cloud + # + # @default: global.cloud.clientSecret + clientSecret: + # The name of the Kubernetes secret that holds the client secret. + # @type: string + secretName: null + # The key within the Kubernetes secret that holds the client secret. + # @type: string + secretKey: null + + initContainer: + # The resource settings for consul-telemetry-collector initContainer. + # @recurse: false + # @type: map + resources: {} + + # Optional YAML string to specify a nodeSelector config. + # @type: string + nodeSelector: null + + # Optional priorityClassName. + # @type: string + priorityClassName: "" + + # A list of extra environment variables to set within the deployment. + # These could be used to include proxy settings required for cloud auto-join + # feature, in case kubernetes cluster is behind egress http proxies. Additionally, + # it could be used to configure custom consul parameters. + # @type: map + extraEnvironmentVars: {} diff --git a/kubernetes-vault/external-secret.yaml b/kubernetes-vault/external-secret.yaml new file mode 100644 index 0000000..429e765 --- /dev/null +++ b/kubernetes-vault/external-secret.yaml @@ -0,0 +1,39 @@ +--- +apiVersion: external-secrets.io/v1beta1 +kind: SecretStore +metadata: + name: otus + namespace: vault +spec: + retrySettings: + maxRetries: 5 + retryInterval: "10s" + provider: + vault: + server: "http://vault.vault:8200" + path: "otus" + version: "v2" + namespace: "vault" + auth: + kubernetes: + mountPath: "kubernetes" + role: "otus" + serviceAccountRef: + name: "vault-auth" +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: otus + namespace: vault +spec: + refreshInterval: 1h + secretStoreRef: + kind: SecretStore + name: otus + target: + name: otus-cred + creationPolicy: Owner + dataFrom: + - extract: + key: cred \ No newline at end of file diff --git a/kubernetes-vault/external-secrets/Chart.lock b/kubernetes-vault/external-secrets/Chart.lock new file mode 100644 index 0000000..6f01c48 --- /dev/null +++ b/kubernetes-vault/external-secrets/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: bitwarden-sdk-server + repository: oci://ghcr.io/external-secrets/charts + version: v0.3.1 +digest: sha256:2d01e9083fc32c18dca4f9614625e0172e338a663138c2670e5b911645b6b8ee +generated: "2024-08-29T06:56:01.838539+02:00" diff --git a/kubernetes-vault/external-secrets/Chart.yaml b/kubernetes-vault/external-secrets/Chart.yaml new file mode 100644 index 0000000..9c361e1 --- /dev/null +++ b/kubernetes-vault/external-secrets/Chart.yaml @@ -0,0 +1,20 @@ +apiVersion: v2 +appVersion: v0.10.3 +dependencies: +- condition: bitwarden-sdk-server.enabled + name: bitwarden-sdk-server + repository: oci://ghcr.io/external-secrets/charts + version: v0.3.1 +description: External secret management for Kubernetes +home: https://github.com/external-secrets/external-secrets +icon: https://raw.githubusercontent.com/external-secrets/external-secrets/main/assets/eso-logo-large.png +keywords: +- kubernetes-external-secrets +- secrets +kubeVersion: '>= 1.19.0-0' +maintainers: +- email: kellinmcavoy@gmail.com + name: mcavoyk +name: external-secrets +type: application +version: 0.10.3 diff --git a/kubernetes-vault/external-secrets/README.md b/kubernetes-vault/external-secrets/README.md new file mode 100644 index 0000000..24cda82 --- /dev/null +++ b/kubernetes-vault/external-secrets/README.md @@ -0,0 +1,225 @@ +# External Secrets + +

external-secrets

+ +[//]: # (README.md generated by gotmpl. DO NOT EDIT.) + +![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![Version: 0.10.3](https://img.shields.io/badge/Version-0.10.3-informational?style=flat-square) + +External secret management for Kubernetes + +## TL;DR +```bash +helm repo add external-secrets https://charts.external-secrets.io +helm install external-secrets external-secrets/external-secrets +``` + +## Installing the Chart +To install the chart with the release name `external-secrets`: +```bash +helm install external-secrets external-secrets/external-secrets +``` + +### Custom Resources +By default, the chart will install external-secrets CRDs, this can be controlled with `installCRDs` value. + +## Uninstalling the Chart +To uninstall the `external-secrets` deployment: +```bash +helm uninstall external-secrets +``` +The command removes all the Kubernetes components associated with the chart and deletes the release. + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| affinity | object | `{}` | | +| bitwarden-sdk-server.enabled | bool | `false` | | +| certController.affinity | object | `{}` | | +| certController.create | bool | `true` | Specifies whether a certificate controller deployment be created. | +| certController.deploymentAnnotations | object | `{}` | Annotations to add to Deployment | +| certController.extraArgs | object | `{}` | | +| certController.extraEnv | list | `[]` | | +| certController.extraVolumeMounts | list | `[]` | | +| certController.extraVolumes | list | `[]` | | +| certController.fullnameOverride | string | `""` | | +| certController.hostNetwork | bool | `false` | Run the certController on the host network | +| certController.image.flavour | string | `""` | | +| certController.image.pullPolicy | string | `"IfNotPresent"` | | +| certController.image.repository | string | `"ghcr.io/external-secrets/external-secrets"` | | +| certController.image.tag | string | `""` | | +| certController.imagePullSecrets | list | `[]` | | +| certController.log | object | `{"level":"info","timeEncoding":"epoch"}` | Specifices Log Params to the Webhook | +| certController.metrics.listen.port | int | `8080` | | +| certController.metrics.service.annotations | object | `{}` | Additional service annotations | +| certController.metrics.service.enabled | bool | `false` | Enable if you use another monitoring tool than Prometheus to scrape the metrics | +| certController.metrics.service.port | int | `8080` | Metrics service port to scrape | +| certController.nameOverride | string | `""` | | +| certController.nodeSelector | object | `{}` | | +| certController.podAnnotations | object | `{}` | Annotations to add to Pod | +| certController.podDisruptionBudget | object | `{"enabled":false,"minAvailable":1}` | Pod disruption budget - for more details see https://kubernetes.io/docs/concepts/workloads/pods/disruptions/ | +| certController.podLabels | object | `{}` | | +| certController.podSecurityContext.enabled | bool | `true` | | +| certController.priorityClassName | string | `""` | Pod priority class name. | +| certController.rbac.create | bool | `true` | Specifies whether role and rolebinding resources should be created. | +| certController.readinessProbe.address | string | `""` | Address for readiness probe | +| certController.readinessProbe.port | int | `8081` | ReadinessProbe port for kubelet | +| certController.replicaCount | int | `1` | | +| certController.requeueInterval | string | `"5m"` | | +| certController.resources | object | `{}` | | +| certController.revisionHistoryLimit | int | `10` | Specifies the amount of historic ReplicaSets k8s should keep (see https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#clean-up-policy) | +| certController.securityContext.allowPrivilegeEscalation | bool | `false` | | +| certController.securityContext.capabilities.drop[0] | string | `"ALL"` | | +| certController.securityContext.enabled | bool | `true` | | +| certController.securityContext.readOnlyRootFilesystem | bool | `true` | | +| certController.securityContext.runAsNonRoot | bool | `true` | | +| certController.securityContext.runAsUser | int | `1000` | | +| certController.securityContext.seccompProfile.type | string | `"RuntimeDefault"` | | +| certController.serviceAccount.annotations | object | `{}` | Annotations to add to the service account. | +| certController.serviceAccount.automount | bool | `true` | Automounts the service account token in all containers of the pod | +| certController.serviceAccount.create | bool | `true` | Specifies whether a service account should be created. | +| certController.serviceAccount.extraLabels | object | `{}` | Extra Labels to add to the service account. | +| certController.serviceAccount.name | string | `""` | The name of the service account to use. If not set and create is true, a name is generated using the fullname template. | +| certController.tolerations | list | `[]` | | +| certController.topologySpreadConstraints | list | `[]` | | +| commonLabels | object | `{}` | Additional labels added to all helm chart resources. | +| concurrent | int | `1` | Specifies the number of concurrent ExternalSecret Reconciles external-secret executes at a time. | +| controllerClass | string | `""` | If set external secrets will filter matching Secret Stores with the appropriate controller values. | +| crds.annotations | object | `{}` | | +| crds.conversion.enabled | bool | `true` | | +| crds.createClusterExternalSecret | bool | `true` | If true, create CRDs for Cluster External Secret. | +| crds.createClusterSecretStore | bool | `true` | If true, create CRDs for Cluster Secret Store. | +| crds.createPushSecret | bool | `true` | If true, create CRDs for Push Secret. | +| createOperator | bool | `true` | Specifies whether an external secret operator deployment be created. | +| deploymentAnnotations | object | `{}` | Annotations to add to Deployment | +| dnsConfig | object | `{}` | Specifies `dnsOptions` to deployment | +| dnsPolicy | string | `"ClusterFirst"` | Specifies `dnsPolicy` to deployment | +| extendedMetricLabels | bool | `false` | If true external secrets will use recommended kubernetes annotations as prometheus metric labels. | +| extraArgs | object | `{}` | | +| extraContainers | list | `[]` | | +| extraEnv | list | `[]` | | +| extraObjects | list | `[]` | | +| extraVolumeMounts | list | `[]` | | +| extraVolumes | list | `[]` | | +| fullnameOverride | string | `""` | | +| global.affinity | object | `{}` | | +| global.compatibility.openshift.adaptSecurityContext | string | `"auto"` | Manages the securityContext properties to make them compatible with OpenShift. Possible values: auto - Apply configurations if it is detected that OpenShift is the target platform. force - Always apply configurations. disabled - No modification applied. | +| global.nodeSelector | object | `{}` | | +| global.tolerations | list | `[]` | | +| global.topologySpreadConstraints | list | `[]` | | +| hostNetwork | bool | `false` | Run the controller on the host network | +| image.flavour | string | `""` | The flavour of tag you want to use There are different image flavours available, like distroless and ubi. Please see GitHub release notes for image tags for these flavors. By default, the distroless image is used. | +| image.pullPolicy | string | `"IfNotPresent"` | | +| image.repository | string | `"ghcr.io/external-secrets/external-secrets"` | | +| image.tag | string | `""` | The image tag to use. The default is the chart appVersion. | +| imagePullSecrets | list | `[]` | | +| installCRDs | bool | `true` | If set, install and upgrade CRDs through helm chart. | +| leaderElect | bool | `false` | If true, external-secrets will perform leader election between instances to ensure no more than one instance of external-secrets operates at a time. | +| log | object | `{"level":"info","timeEncoding":"epoch"}` | Specifices Log Params to the Webhook | +| metrics.listen.port | int | `8080` | | +| metrics.service.annotations | object | `{}` | Additional service annotations | +| metrics.service.enabled | bool | `false` | Enable if you use another monitoring tool than Prometheus to scrape the metrics | +| metrics.service.port | int | `8080` | Metrics service port to scrape | +| nameOverride | string | `""` | | +| namespaceOverride | string | `""` | | +| nodeSelector | object | `{}` | | +| podAnnotations | object | `{}` | Annotations to add to Pod | +| podDisruptionBudget | object | `{"enabled":false,"minAvailable":1}` | Pod disruption budget - for more details see https://kubernetes.io/docs/concepts/workloads/pods/disruptions/ | +| podLabels | object | `{}` | | +| podSecurityContext.enabled | bool | `true` | | +| podSpecExtra | object | `{}` | Any extra pod spec on the deployment | +| priorityClassName | string | `""` | Pod priority class name. | +| processClusterExternalSecret | bool | `true` | if true, the operator will process cluster external secret. Else, it will ignore them. | +| processClusterStore | bool | `true` | if true, the operator will process cluster store. Else, it will ignore them. | +| processPushSecret | bool | `true` | if true, the operator will process push secret. Else, it will ignore them. | +| rbac.create | bool | `true` | Specifies whether role and rolebinding resources should be created. | +| rbac.servicebindings.create | bool | `true` | Specifies whether a clusterrole to give servicebindings read access should be created. | +| replicaCount | int | `1` | | +| resources | object | `{}` | | +| revisionHistoryLimit | int | `10` | Specifies the amount of historic ReplicaSets k8s should keep (see https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#clean-up-policy) | +| scopedNamespace | string | `""` | If set external secrets are only reconciled in the provided namespace | +| scopedRBAC | bool | `false` | Must be used with scopedNamespace. If true, create scoped RBAC roles under the scoped namespace and implicitly disable cluster stores and cluster external secrets | +| securityContext.allowPrivilegeEscalation | bool | `false` | | +| securityContext.capabilities.drop[0] | string | `"ALL"` | | +| securityContext.enabled | bool | `true` | | +| securityContext.readOnlyRootFilesystem | bool | `true` | | +| securityContext.runAsNonRoot | bool | `true` | | +| securityContext.runAsUser | int | `1000` | | +| securityContext.seccompProfile.type | string | `"RuntimeDefault"` | | +| service.ipFamilies | list | `[]` | Sets the families that should be supported and the order in which they should be applied to ClusterIP as well. Can be IPv4 and/or IPv6. | +| service.ipFamilyPolicy | string | `""` | Set the ip family policy to configure dual-stack see [Configure dual-stack](https://kubernetes.io/docs/concepts/services-networking/dual-stack/#services) | +| serviceAccount.annotations | object | `{}` | Annotations to add to the service account. | +| serviceAccount.automount | bool | `true` | Automounts the service account token in all containers of the pod | +| serviceAccount.create | bool | `true` | Specifies whether a service account should be created. | +| serviceAccount.extraLabels | object | `{}` | Extra Labels to add to the service account. | +| serviceAccount.name | string | `""` | The name of the service account to use. If not set and create is true, a name is generated using the fullname template. | +| serviceMonitor.additionalLabels | object | `{}` | Additional labels | +| serviceMonitor.enabled | bool | `false` | Specifies whether to create a ServiceMonitor resource for collecting Prometheus metrics | +| serviceMonitor.honorLabels | bool | `false` | Let prometheus add an exported_ prefix to conflicting labels | +| serviceMonitor.interval | string | `"30s"` | Interval to scrape metrics | +| serviceMonitor.metricRelabelings | list | `[]` | Metric relabel configs to apply to samples before ingestion. [Metric Relabeling](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs) | +| serviceMonitor.namespace | string | `""` | namespace where you want to install ServiceMonitors | +| serviceMonitor.relabelings | list | `[]` | Relabel configs to apply to samples before ingestion. [Relabeling](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config) | +| serviceMonitor.scrapeTimeout | string | `"25s"` | Timeout if metrics can't be retrieved in given time interval | +| tolerations | list | `[]` | | +| topologySpreadConstraints | list | `[]` | | +| webhook.affinity | object | `{}` | | +| webhook.certCheckInterval | string | `"5m"` | Specifices the time to check if the cert is valid | +| webhook.certDir | string | `"/tmp/certs"` | | +| webhook.certManager.addInjectorAnnotations | bool | `true` | Automatically add the cert-manager.io/inject-ca-from annotation to the webhooks and CRDs. As long as you have the cert-manager CA Injector enabled, this will automatically setup your webhook's CA to the one used by cert-manager. See https://cert-manager.io/docs/concepts/ca-injector | +| webhook.certManager.cert.annotations | object | `{}` | Add extra annotations to the Certificate resource. | +| webhook.certManager.cert.create | bool | `true` | Create a certificate resource within this chart. See https://cert-manager.io/docs/usage/certificate/ | +| webhook.certManager.cert.duration | string | `"8760h"` | Set the requested duration (i.e. lifetime) of the Certificate. See https://cert-manager.io/docs/reference/api-docs/#cert-manager.io/v1.CertificateSpec One year by default. | +| webhook.certManager.cert.issuerRef | object | `{"group":"cert-manager.io","kind":"Issuer","name":"my-issuer"}` | For the Certificate created by this chart, setup the issuer. See https://cert-manager.io/docs/reference/api-docs/#cert-manager.io/v1.IssuerSpec | +| webhook.certManager.cert.renewBefore | string | `""` | How long before the currently issued certificate’s expiry cert-manager should renew the certificate. See https://cert-manager.io/docs/reference/api-docs/#cert-manager.io/v1.CertificateSpec Note that renewBefore should be greater than .webhook.lookaheadInterval since the webhook will check this far in advance that the certificate is valid. | +| webhook.certManager.enabled | bool | `false` | Enabling cert-manager support will disable the built in secret and switch to using cert-manager (installed separately) to automatically issue and renew the webhook certificate. This chart does not install cert-manager for you, See https://cert-manager.io/docs/ | +| webhook.create | bool | `true` | Specifies whether a webhook deployment be created. | +| webhook.deploymentAnnotations | object | `{}` | Annotations to add to Deployment | +| webhook.extraArgs | object | `{}` | | +| webhook.extraEnv | list | `[]` | | +| webhook.extraVolumeMounts | list | `[]` | | +| webhook.extraVolumes | list | `[]` | | +| webhook.failurePolicy | string | `"Fail"` | Specifies whether validating webhooks should be created with failurePolicy: Fail or Ignore | +| webhook.fullnameOverride | string | `""` | | +| webhook.hostNetwork | bool | `false` | Specifies if webhook pod should use hostNetwork or not. | +| webhook.image.flavour | string | `""` | The flavour of tag you want to use | +| webhook.image.pullPolicy | string | `"IfNotPresent"` | | +| webhook.image.repository | string | `"ghcr.io/external-secrets/external-secrets"` | | +| webhook.image.tag | string | `""` | The image tag to use. The default is the chart appVersion. | +| webhook.imagePullSecrets | list | `[]` | | +| webhook.log | object | `{"level":"info","timeEncoding":"epoch"}` | Specifices Log Params to the Webhook | +| webhook.lookaheadInterval | string | `""` | Specifices the lookaheadInterval for certificate validity | +| webhook.metrics.listen.port | int | `8080` | | +| webhook.metrics.service.annotations | object | `{}` | Additional service annotations | +| webhook.metrics.service.enabled | bool | `false` | Enable if you use another monitoring tool than Prometheus to scrape the metrics | +| webhook.metrics.service.port | int | `8080` | Metrics service port to scrape | +| webhook.nameOverride | string | `""` | | +| webhook.nodeSelector | object | `{}` | | +| webhook.podAnnotations | object | `{}` | Annotations to add to Pod | +| webhook.podDisruptionBudget | object | `{"enabled":false,"minAvailable":1}` | Pod disruption budget - for more details see https://kubernetes.io/docs/concepts/workloads/pods/disruptions/ | +| webhook.podLabels | object | `{}` | | +| webhook.podSecurityContext.enabled | bool | `true` | | +| webhook.port | int | `10250` | The port the webhook will listen to | +| webhook.priorityClassName | string | `""` | Pod priority class name. | +| webhook.rbac.create | bool | `true` | Specifies whether role and rolebinding resources should be created. | +| webhook.readinessProbe.address | string | `""` | Address for readiness probe | +| webhook.readinessProbe.port | int | `8081` | ReadinessProbe port for kubelet | +| webhook.replicaCount | int | `1` | | +| webhook.resources | object | `{}` | | +| webhook.revisionHistoryLimit | int | `10` | Specifies the amount of historic ReplicaSets k8s should keep (see https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#clean-up-policy) | +| webhook.secretAnnotations | object | `{}` | Annotations to add to Secret | +| webhook.securityContext.allowPrivilegeEscalation | bool | `false` | | +| webhook.securityContext.capabilities.drop[0] | string | `"ALL"` | | +| webhook.securityContext.enabled | bool | `true` | | +| webhook.securityContext.readOnlyRootFilesystem | bool | `true` | | +| webhook.securityContext.runAsNonRoot | bool | `true` | | +| webhook.securityContext.runAsUser | int | `1000` | | +| webhook.securityContext.seccompProfile.type | string | `"RuntimeDefault"` | | +| webhook.serviceAccount.annotations | object | `{}` | Annotations to add to the service account. | +| webhook.serviceAccount.automount | bool | `true` | Automounts the service account token in all containers of the pod | +| webhook.serviceAccount.create | bool | `true` | Specifies whether a service account should be created. | +| webhook.serviceAccount.extraLabels | object | `{}` | Extra Labels to add to the service account. | +| webhook.serviceAccount.name | string | `""` | The name of the service account to use. If not set and create is true, a name is generated using the fullname template. | +| webhook.tolerations | list | `[]` | | +| webhook.topologySpreadConstraints | list | `[]` | | diff --git a/kubernetes-vault/external-secrets/charts/bitwarden-sdk-server/.helmignore b/kubernetes-vault/external-secrets/charts/bitwarden-sdk-server/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/kubernetes-vault/external-secrets/charts/bitwarden-sdk-server/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/kubernetes-vault/external-secrets/charts/bitwarden-sdk-server/Chart.yaml b/kubernetes-vault/external-secrets/charts/bitwarden-sdk-server/Chart.yaml new file mode 100644 index 0000000..64d6f38 --- /dev/null +++ b/kubernetes-vault/external-secrets/charts/bitwarden-sdk-server/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +appVersion: v0.3.1 +description: A Helm chart for Kubernetes +name: bitwarden-sdk-server +type: application +version: v0.3.1 diff --git a/kubernetes-vault/external-secrets/charts/bitwarden-sdk-server/templates/NOTES.txt b/kubernetes-vault/external-secrets/charts/bitwarden-sdk-server/templates/NOTES.txt new file mode 100644 index 0000000..46b671c --- /dev/null +++ b/kubernetes-vault/external-secrets/charts/bitwarden-sdk-server/templates/NOTES.txt @@ -0,0 +1,22 @@ +1. Get the application URL by running these commands: +{{- if .Values.ingress.enabled }} +{{- range $host := .Values.ingress.hosts }} + {{- range .paths }} + http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }} + {{- end }} +{{- end }} +{{- else if contains "NodePort" .Values.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "bitwarden-sdk-server.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT +{{- else if contains "LoadBalancer" .Values.service.type }} + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "bitwarden-sdk-server.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "bitwarden-sdk-server.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") + echo http://$SERVICE_IP:{{ .Values.service.port }} +{{- else if contains "ClusterIP" .Values.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "bitwarden-sdk-server.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") + echo "Visit http://127.0.0.1:8080 to use your application" + kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT +{{- end }} diff --git a/kubernetes-vault/external-secrets/charts/bitwarden-sdk-server/templates/_helpers.tpl b/kubernetes-vault/external-secrets/charts/bitwarden-sdk-server/templates/_helpers.tpl new file mode 100644 index 0000000..a5e0da3 --- /dev/null +++ b/kubernetes-vault/external-secrets/charts/bitwarden-sdk-server/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "bitwarden-sdk-server.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "bitwarden-sdk-server.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "bitwarden-sdk-server.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "bitwarden-sdk-server.labels" -}} +helm.sh/chart: {{ include "bitwarden-sdk-server.chart" . }} +{{ include "bitwarden-sdk-server.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "bitwarden-sdk-server.selectorLabels" -}} +app.kubernetes.io/name: {{ include "bitwarden-sdk-server.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "bitwarden-sdk-server.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "bitwarden-sdk-server.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/external-secrets/charts/bitwarden-sdk-server/templates/deployment.yaml b/kubernetes-vault/external-secrets/charts/bitwarden-sdk-server/templates/deployment.yaml new file mode 100644 index 0000000..06e2882 --- /dev/null +++ b/kubernetes-vault/external-secrets/charts/bitwarden-sdk-server/templates/deployment.yaml @@ -0,0 +1,77 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "bitwarden-sdk-server.fullname" . }} + labels: + {{- include "bitwarden-sdk-server.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + {{- include "bitwarden-sdk-server.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "bitwarden-sdk-server.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "bitwarden-sdk-server.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + {{- if not .Values.image.tls.enabled }} + args: + - --insecure + {{- end }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- if .Values.image.tls.enabled }} + volumeMounts: + {{- toYaml .Values.image.tls.volumeMounts | nindent 10 }} + {{- end}} + ports: + - name: http + containerPort: {{ .Values.service.port }} + protocol: TCP + livenessProbe: + httpGet: + path: /live + port: http + {{- if .Values.image.tls.enabled }} + scheme: HTTPS + {{- end }} + readinessProbe: + httpGet: + path: /ready + port: http + {{- if .Values.image.tls.enabled }} + scheme: HTTPS + {{- end }} + resources: + {{- toYaml .Values.resources | nindent 12 }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.image.tls.enabled }} + volumes: + {{- toYaml .Values.image.tls.volumes | nindent 8 }} + {{- end}} diff --git a/kubernetes-vault/external-secrets/charts/bitwarden-sdk-server/templates/service.yaml b/kubernetes-vault/external-secrets/charts/bitwarden-sdk-server/templates/service.yaml new file mode 100644 index 0000000..88e2d66 --- /dev/null +++ b/kubernetes-vault/external-secrets/charts/bitwarden-sdk-server/templates/service.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "bitwarden-sdk-server.fullname" . }} + labels: + {{- include "bitwarden-sdk-server.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: http + name: http + selector: + {{- include "bitwarden-sdk-server.selectorLabels" . | nindent 4 }} diff --git a/kubernetes-vault/external-secrets/charts/bitwarden-sdk-server/templates/serviceaccount.yaml b/kubernetes-vault/external-secrets/charts/bitwarden-sdk-server/templates/serviceaccount.yaml new file mode 100644 index 0000000..fef7bad --- /dev/null +++ b/kubernetes-vault/external-secrets/charts/bitwarden-sdk-server/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "bitwarden-sdk-server.serviceAccountName" . }} + labels: + {{- include "bitwarden-sdk-server.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/kubernetes-vault/external-secrets/charts/bitwarden-sdk-server/tests/__snapshot__/deployment_test.yaml.snap b/kubernetes-vault/external-secrets/charts/bitwarden-sdk-server/tests/__snapshot__/deployment_test.yaml.snap new file mode 100644 index 0000000..2fbcdb1 --- /dev/null +++ b/kubernetes-vault/external-secrets/charts/bitwarden-sdk-server/tests/__snapshot__/deployment_test.yaml.snap @@ -0,0 +1,60 @@ +deployment should match snapshot: + 1: | + apiVersion: apps/v1 + kind: Deployment + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: bitwarden-sdk-server + app.kubernetes.io/version: 1.16.0 + helm.sh/chart: bitwarden-sdk-server-0.1.0 + name: bitwarden-sdk-server + spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/name: bitwarden-sdk-server + template: + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/name: bitwarden-sdk-server + spec: + containers: + - image: ghcr.io/external-secrets/bitwarden-sdk-server:v0.8.0 + imagePullPolicy: IfNotPresent + livenessProbe: + httpGet: + path: /live + port: http + scheme: HTTPS + name: bitwarden-sdk-server + ports: + - containerPort: 9998 + name: http + protocol: TCP + readinessProbe: + httpGet: + path: /ready + port: http + scheme: HTTPS + resources: {} + securityContext: {} + volumeMounts: + - mountPath: /certs + name: bitwarden-tls-certs + securityContext: {} + serviceAccountName: bitwarden-sdk-server + volumes: + - name: bitwarden-tls-certs + secret: + items: + - key: tls.crt + path: cert.pem + - key: tls.key + path: key.pem + - key: ca.crt + path: ca.pem + secretName: bitwarden-tls-certs diff --git a/kubernetes-vault/external-secrets/charts/bitwarden-sdk-server/tests/deployment_test.yaml b/kubernetes-vault/external-secrets/charts/bitwarden-sdk-server/tests/deployment_test.yaml new file mode 100644 index 0000000..bb4e2f4 --- /dev/null +++ b/kubernetes-vault/external-secrets/charts/bitwarden-sdk-server/tests/deployment_test.yaml @@ -0,0 +1,9 @@ +suite: test deployment +templates: + - deployment.yaml +tests: + - it: deployment should match snapshot + set: + image.tag: v0.8.0 + asserts: + - matchSnapshot: {} diff --git a/kubernetes-vault/external-secrets/charts/bitwarden-sdk-server/values.yaml b/kubernetes-vault/external-secrets/charts/bitwarden-sdk-server/values.yaml new file mode 100644 index 0000000..f0424af --- /dev/null +++ b/kubernetes-vault/external-secrets/charts/bitwarden-sdk-server/values.yaml @@ -0,0 +1,98 @@ +# Default values for bitwarden-sdk-server. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +replicaCount: 1 + +image: + repository: ghcr.io/external-secrets/bitwarden-sdk-server + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "" + tls: + enabled: true + volumeMounts: + - mountPath: "/certs" + name: "bitwarden-tls-certs" + volumes: + - name: "bitwarden-tls-certs" + secret: + secretName: "bitwarden-tls-certs" + items: + - key: "tls.crt" + path: "cert.pem" + - key: "tls.key" + path: "key.pem" + - key: "ca.crt" + path: "ca.pem" + +imagePullSecrets: [] +nameOverride: "bitwarden-sdk-server" +fullnameOverride: "bitwarden-sdk-server" + +serviceAccount: + # Specifies whether a service account should be created + create: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + type: ClusterIP + port: 9998 + +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 do 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: {} diff --git a/kubernetes-vault/external-secrets/templates/NOTES.txt b/kubernetes-vault/external-secrets/templates/NOTES.txt new file mode 100644 index 0000000..ffa0fc7 --- /dev/null +++ b/kubernetes-vault/external-secrets/templates/NOTES.txt @@ -0,0 +1,7 @@ +external-secrets has been deployed successfully in namespace {{ template "external-secrets.namespace" . }}! + +In order to begin using ExternalSecrets, you will need to set up a SecretStore +or ClusterSecretStore resource (for example, by creating a 'vault' SecretStore). + +More information on the different types of SecretStores and how to configure them +can be found in our Github: {{ .Chart.Home }} diff --git a/kubernetes-vault/external-secrets/templates/_helpers.tpl b/kubernetes-vault/external-secrets/templates/_helpers.tpl new file mode 100644 index 0000000..d5eea07 --- /dev/null +++ b/kubernetes-vault/external-secrets/templates/_helpers.tpl @@ -0,0 +1,198 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "external-secrets.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "external-secrets.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 }} + +{{/* +Define namespace of chart, useful for multi-namespace deployments +*/}} +{{- define "external-secrets.namespace" -}} +{{- if .Values.namespaceOverride }} +{{- .Values.namespaceOverride }} +{{- else }} +{{- .Release.Namespace }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "external-secrets.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "external-secrets.labels" -}} +helm.sh/chart: {{ include "external-secrets.chart" . }} +{{ include "external-secrets.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 }} + +{{- define "external-secrets-webhook.labels" -}} +helm.sh/chart: {{ include "external-secrets.chart" . }} +{{ include "external-secrets-webhook.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 }} + +{{- define "external-secrets-webhook-metrics.labels" -}} +{{ include "external-secrets-webhook.selectorLabels" . }} +app.kubernetes.io/metrics: "webhook" +{{- with .Values.commonLabels }} +{{ toYaml . }} +{{- end }} +{{- end }} + +{{- define "external-secrets-cert-controller.labels" -}} +helm.sh/chart: {{ include "external-secrets.chart" . }} +{{ include "external-secrets-cert-controller.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 }} + +{{- define "external-secrets-cert-controller-metrics.labels" -}} +{{ include "external-secrets-cert-controller.selectorLabels" . }} +app.kubernetes.io/metrics: "cert-controller" +{{- with .Values.commonLabels }} +{{ toYaml . }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "external-secrets.selectorLabels" -}} +app.kubernetes.io/name: {{ include "external-secrets.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} +{{- define "external-secrets-webhook.selectorLabels" -}} +app.kubernetes.io/name: {{ include "external-secrets.name" . }}-webhook +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} +{{- define "external-secrets-cert-controller.selectorLabels" -}} +app.kubernetes.io/name: {{ include "external-secrets.name" . }}-cert-controller +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} +{{/* +Create the name of the service account to use +*/}} +{{- define "external-secrets.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "external-secrets.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "external-secrets-webhook.serviceAccountName" -}} +{{- if .Values.webhook.serviceAccount.create }} +{{- default "external-secrets-webhook" .Values.webhook.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.webhook.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "external-secrets-cert-controller.serviceAccountName" -}} +{{- if .Values.certController.serviceAccount.create }} +{{- default "external-secrets-cert-controller" .Values.certController.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.certController.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Determine the image to use, including if using a flavour. +*/}} +{{- define "external-secrets.image" -}} +{{- if .image.flavour -}} +{{ printf "%s:%s-%s" .image.repository (.image.tag | default .chartAppVersion) .image.flavour }} +{{- else }} +{{ printf "%s:%s" .image.repository (.image.tag | default .chartAppVersion) }} +{{- end }} +{{- end }} + +{{/* +Renders a complete tree, even values that contains template. +*/}} +{{- define "external-secrets.render" -}} + {{- if typeIs "string" .value }} + {{- tpl .value .context }} + {{ else }} + {{- tpl (.value | toYaml) .context }} + {{- end }} +{{- end -}} + +{{/* +Return true if the OpenShift is the detected platform +Usage: +{{- include "external-secrets.isOpenShift" . -}} +*/}} +{{- define "external-secrets.isOpenShift" -}} +{{- if .Capabilities.APIVersions.Has "security.openshift.io/v1" -}} +{{- true -}} +{{- end -}} +{{- end -}} + +{{/* +Render the securityContext based on the provided securityContext + {{- include "external-secrets.renderSecurityContext" (dict "securityContext" .Values.securityContext "context" $) -}} +*/}} +{{- define "external-secrets.renderSecurityContext" -}} +{{- $adaptedContext := .securityContext -}} +{{- if .context.Values.global.compatibility -}} + {{- if .context.Values.global.compatibility.openshift -}} + {{- if or (eq .context.Values.global.compatibility.openshift.adaptSecurityContext "force") (and (eq .context.Values.global.compatibility.openshift.adaptSecurityContext "auto") (include "external-secrets.isOpenShift" .context)) -}} + {{/* Remove OpenShift managed fields */}} + {{- $adaptedContext = omit $adaptedContext "fsGroup" "runAsUser" "runAsGroup" -}} + {{- if not .securityContext.seLinuxOptions -}} + {{- $adaptedContext = omit $adaptedContext "seLinuxOptions" -}} + {{- end -}} + {{- end -}} + {{- end -}} +{{- end -}} +{{- omit $adaptedContext "enabled" | toYaml -}} +{{- end -}} diff --git a/kubernetes-vault/external-secrets/templates/cert-controller-deployment.yaml b/kubernetes-vault/external-secrets/templates/cert-controller-deployment.yaml new file mode 100644 index 0000000..a843f04 --- /dev/null +++ b/kubernetes-vault/external-secrets/templates/cert-controller-deployment.yaml @@ -0,0 +1,124 @@ +{{- if and .Values.certController.create (not .Values.webhook.certManager.enabled) }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "external-secrets.fullname" . }}-cert-controller + namespace: {{ template "external-secrets.namespace" . }} + labels: + {{- include "external-secrets-cert-controller.labels" . | nindent 4 }} + {{- with .Values.certController.deploymentAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.certController.replicaCount }} + revisionHistoryLimit: {{ .Values.certController.revisionHistoryLimit }} + selector: + matchLabels: + {{- include "external-secrets-cert-controller.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.certController.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "external-secrets-cert-controller.labels" . | nindent 8 }} + {{- with .Values.certController.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.certController.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "external-secrets-cert-controller.serviceAccountName" . }} + automountServiceAccountToken: {{ .Values.certController.serviceAccount.automount }} + {{- with .Values.certController.podSecurityContext }} + {{- if and (.enabled) (gt (keys . | len) 1) }} + securityContext: + {{- include "external-secrets.renderSecurityContext" (dict "securityContext" . "context" $) | nindent 8 }} + {{- end }} + {{- end }} + hostNetwork: {{ .Values.certController.hostNetwork }} + containers: + - name: cert-controller + {{- with .Values.certController.securityContext }} + {{- if and (.enabled) (gt (keys . | len) 1) }} + securityContext: + {{- include "external-secrets.renderSecurityContext" (dict "securityContext" . "context" $) | nindent 12 }} + {{- end }} + {{- end }} + image: {{ include "external-secrets.image" (dict "chartAppVersion" .Chart.AppVersion "image" .Values.certController.image) | trim }} + imagePullPolicy: {{ .Values.certController.image.pullPolicy }} + args: + - certcontroller + - --crd-requeue-interval={{ .Values.certController.requeueInterval }} + - --service-name={{ include "external-secrets.fullname" . }}-webhook + - --service-namespace={{ template "external-secrets.namespace" . }} + - --secret-name={{ include "external-secrets.fullname" . }}-webhook + - --secret-namespace={{ template "external-secrets.namespace" . }} + - --metrics-addr=:{{ .Values.certController.metrics.listen.port }} + - --healthz-addr={{ .Values.certController.readinessProbe.address }}:{{ .Values.certController.readinessProbe.port }} + - --loglevel={{ .Values.certController.log.level }} + - --zap-time-encoding={{ .Values.certController.log.timeEncoding }} + {{- if not .Values.crds.createClusterSecretStore }} + - --crd-names=externalsecrets.external-secrets.io + - --crd-names=secretstores.external-secrets.io + {{- end }} + {{- if .Values.installCRDs }} + - --enable-partial-cache=true + {{- end }} + {{- range $key, $value := .Values.certController.extraArgs }} + {{- if $value }} + - --{{ $key }}={{ $value }} + {{- else }} + - --{{ $key }} + {{- end }} + {{- end }} + ports: + - containerPort: {{ .Values.certController.metrics.listen.port }} + protocol: TCP + name: metrics + readinessProbe: + httpGet: + port: {{ .Values.certController.readinessProbe.port }} + path: /readyz + initialDelaySeconds: 20 + periodSeconds: 5 + {{- with .Values.certController.extraEnv }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.certController.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.certController.extraVolumeMounts }} + volumeMounts: + {{- toYaml .Values.certController.extraVolumeMounts | nindent 12 }} + {{- end }} + {{- if .Values.certController.extraVolumes }} + volumes: + {{- toYaml .Values.certController.extraVolumes | nindent 8 }} + {{- end }} + {{- with .Values.certController.nodeSelector | default .Values.global.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.certController.affinity | default .Values.global.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.certController.tolerations | default .Values.global.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.certController.topologySpreadConstraints | default .Values.global.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.certController.priorityClassName }} + priorityClassName: {{ .Values.certController.priorityClassName }} + {{- end }} +{{- end }} diff --git a/kubernetes-vault/external-secrets/templates/cert-controller-poddisruptionbudget.yaml b/kubernetes-vault/external-secrets/templates/cert-controller-poddisruptionbudget.yaml new file mode 100644 index 0000000..e61cb8e --- /dev/null +++ b/kubernetes-vault/external-secrets/templates/cert-controller-poddisruptionbudget.yaml @@ -0,0 +1,19 @@ +{{- if and .Values.certController.create .Values.certController.podDisruptionBudget.enabled (not .Values.webhook.certManager.enabled) }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "external-secrets.fullname" . }}-cert-controller-pdb + namespace: {{ template "external-secrets.namespace" . }} + labels: + {{- include "external-secrets-cert-controller.labels" . | nindent 4 }} +spec: + {{- if .Values.certController.podDisruptionBudget.minAvailable }} + minAvailable: {{ .Values.certController.podDisruptionBudget.minAvailable }} + {{- end }} + {{- if .Values.certController.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ .Values.certController.podDisruptionBudget.maxUnavailable }} + {{- end }} + selector: + matchLabels: + {{- include "external-secrets-cert-controller.selectorLabels" . | nindent 6 }} +{{- end }} diff --git a/kubernetes-vault/external-secrets/templates/cert-controller-rbac.yaml b/kubernetes-vault/external-secrets/templates/cert-controller-rbac.yaml new file mode 100644 index 0000000..84a0c11 --- /dev/null +++ b/kubernetes-vault/external-secrets/templates/cert-controller-rbac.yaml @@ -0,0 +1,86 @@ +{{- if and .Values.certController.create .Values.certController.rbac.create (not .Values.webhook.certManager.enabled) -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "external-secrets.fullname" . }}-cert-controller + labels: + {{- include "external-secrets-cert-controller.labels" . | nindent 4 }} +rules: + - apiGroups: + - "apiextensions.k8s.io" + resources: + - "customresourcedefinitions" + verbs: + - "get" + - "list" + - "watch" + - "update" + - "patch" + - apiGroups: + - "admissionregistration.k8s.io" + resources: + - "validatingwebhookconfigurations" + verbs: + - "list" + - "watch" + - "get" + - apiGroups: + - "admissionregistration.k8s.io" + resources: + - "validatingwebhookconfigurations" + resourceNames: + - "secretstore-validate" + - "externalsecret-validate" + verbs: + - "update" + - "patch" + - apiGroups: + - "" + resources: + - "endpoints" + verbs: + - "list" + - "get" + - "watch" + - apiGroups: + - "" + resources: + - "events" + verbs: + - "create" + - "patch" + - apiGroups: + - "" + resources: + - "secrets" + verbs: + - "get" + - "list" + - "watch" + - "update" + - "patch" + - apiGroups: + - "coordination.k8s.io" + resources: + - "leases" + verbs: + - "get" + - "create" + - "update" + - "patch" +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "external-secrets.fullname" . }}-cert-controller + labels: + {{- include "external-secrets-cert-controller.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "external-secrets.fullname" . }}-cert-controller +subjects: + - name: {{ include "external-secrets-cert-controller.serviceAccountName" . }} + namespace: {{ template "external-secrets.namespace" . }} + kind: ServiceAccount +{{- end }} diff --git a/kubernetes-vault/external-secrets/templates/cert-controller-service.yaml b/kubernetes-vault/external-secrets/templates/cert-controller-service.yaml new file mode 100644 index 0000000..12cb4f4 --- /dev/null +++ b/kubernetes-vault/external-secrets/templates/cert-controller-service.yaml @@ -0,0 +1,28 @@ +{{- if and .Values.certController.create .Values.certController.metrics.service.enabled (not .Values.webhook.certManager.enabled) }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "external-secrets.fullname" . }}-cert-controller-metrics + namespace: {{ template "external-secrets.namespace" . }} + labels: + {{- include "external-secrets.labels" . | nindent 4 }} + {{- with .Values.metrics.service.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + type: ClusterIP + {{- if .Values.service.ipFamilyPolicy }} + ipFamilyPolicy: {{ .Values.service.ipFamilyPolicy }} + {{- end }} + {{- if .Values.service.ipFamilies }} + ipFamilies: {{ .Values.service.ipFamilies | toYaml | nindent 2 }} + {{- end }} + ports: + - port: {{ .Values.certController.metrics.service.port }} + protocol: TCP + targetPort: metrics + name: metrics + selector: + {{- include "external-secrets-cert-controller.selectorLabels" . | nindent 4 }} +{{- end }} diff --git a/kubernetes-vault/external-secrets/templates/cert-controller-serviceaccount.yaml b/kubernetes-vault/external-secrets/templates/cert-controller-serviceaccount.yaml new file mode 100644 index 0000000..6a36f9d --- /dev/null +++ b/kubernetes-vault/external-secrets/templates/cert-controller-serviceaccount.yaml @@ -0,0 +1,16 @@ +{{- if and .Values.certController.create .Values.certController.serviceAccount.create (not .Values.webhook.certManager.enabled) -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "external-secrets-cert-controller.serviceAccountName" . }} + namespace: {{ template "external-secrets.namespace" . }} + labels: + {{- include "external-secrets-cert-controller.labels" . | nindent 4 }} + {{- with .Values.certController.serviceAccount.extraLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.certController.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/kubernetes-vault/external-secrets/templates/crds/acraccesstoken.yaml b/kubernetes-vault/external-secrets/templates/crds/acraccesstoken.yaml new file mode 100644 index 0000000..b93e369 --- /dev/null +++ b/kubernetes-vault/external-secrets/templates/crds/acraccesstoken.yaml @@ -0,0 +1,203 @@ +{{- if .Values.installCRDs }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + {{- with .Values.crds.annotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- if and .Values.crds.conversion.enabled .Values.webhook.certManager.enabled .Values.webhook.certManager.addInjectorAnnotations }} + cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/{{ include "external-secrets.fullname" . }}-webhook + {{- end }} + controller-gen.kubebuilder.io/version: v0.16.2 + labels: + external-secrets.io/component: controller + name: acraccesstokens.generators.external-secrets.io +spec: + group: generators.external-secrets.io + names: + categories: + - acraccesstoken + kind: ACRAccessToken + listKind: ACRAccessTokenList + plural: acraccesstokens + shortNames: + - acraccesstoken + singular: acraccesstoken + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + ACRAccessToken returns a Azure Container Registry token + that can be used for pushing/pulling images. + Note: by default it will return an ACR Refresh Token with full access + (depending on the identity). + This can be scoped down to the repository level using .spec.scope. + In case scope is defined it will return an ACR Access Token. + + See docs: https://github.com/Azure/acr/blob/main/docs/AAD-OAuth.md + 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: |- + ACRAccessTokenSpec defines how to generate the access token + e.g. how to authenticate and which registry to use. + see: https://github.com/Azure/acr/blob/main/docs/AAD-OAuth.md#overview + properties: + auth: + properties: + managedIdentity: + description: ManagedIdentity uses Azure Managed Identity to authenticate with Azure. + properties: + identityId: + description: If multiple Managed Identity is assigned to the pod, you can select the one to be used + type: string + type: object + servicePrincipal: + description: ServicePrincipal uses Azure Service Principal credentials to authenticate with Azure. + properties: + secretRef: + description: |- + Configuration used to authenticate with Azure using static + credentials stored in a Kind=Secret. + properties: + clientId: + description: The Azure clientId of the service principle used for authentication. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + clientSecret: + description: The Azure ClientSecret of the service principle used for authentication. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + required: + - secretRef + type: object + workloadIdentity: + description: WorkloadIdentity uses Azure Workload Identity to authenticate with Azure. + properties: + serviceAccountRef: + description: |- + ServiceAccountRef specified the service account + that should be used when authenticating with WorkloadIdentity. + properties: + audiences: + description: |- + Audience specifies the `aud` claim for the service account token + If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity + then this audiences will be appended to the list + items: + type: string + type: array + name: + description: The name of the ServiceAccount resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + required: + - name + type: object + type: object + type: object + environmentType: + default: PublicCloud + description: |- + EnvironmentType specifies the Azure cloud environment endpoints to use for + connecting and authenticating with Azure. By default it points to the public cloud AAD endpoint. + The following endpoints are available, also see here: https://github.com/Azure/go-autorest/blob/main/autorest/azure/environments.go#L152 + PublicCloud, USGovernmentCloud, ChinaCloud, GermanCloud + enum: + - PublicCloud + - USGovernmentCloud + - ChinaCloud + - GermanCloud + type: string + registry: + description: |- + the domain name of the ACR registry + e.g. foobarexample.azurecr.io + type: string + scope: + description: |- + Define the scope for the access token, e.g. pull/push access for a repository. + if not provided it will return a refresh token that has full scope. + Note: you need to pin it down to the repository level, there is no wildcard available. + + examples: + repository:my-repository:pull,push + repository:my-repository:pull + + see docs for details: https://docs.docker.com/registry/spec/auth/scope/ + type: string + tenantId: + description: TenantID configures the Azure Tenant to send requests to. Required for ServicePrincipal auth type. + type: string + required: + - auth + - registry + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- if .Values.crds.conversion.enabled }} + conversion: + strategy: Webhook + webhook: + conversionReviewVersions: + - v1 + clientConfig: + service: + name: {{ include "external-secrets.fullname" . }}-webhook + namespace: {{ .Release.Namespace | quote }} + path: /convert +{{- end }} +{{- end }} diff --git a/kubernetes-vault/external-secrets/templates/crds/clusterexternalsecret.yaml b/kubernetes-vault/external-secrets/templates/crds/clusterexternalsecret.yaml new file mode 100644 index 0000000..53fb399 --- /dev/null +++ b/kubernetes-vault/external-secrets/templates/crds/clusterexternalsecret.yaml @@ -0,0 +1,666 @@ +{{- if and (.Values.installCRDs) (.Values.crds.createClusterExternalSecret) }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + {{- with .Values.crds.annotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- if and .Values.crds.conversion.enabled .Values.webhook.certManager.enabled .Values.webhook.certManager.addInjectorAnnotations }} + cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/{{ include "external-secrets.fullname" . }}-webhook + {{- end }} + controller-gen.kubebuilder.io/version: v0.16.2 + labels: + external-secrets.io/component: controller + name: clusterexternalsecrets.external-secrets.io +spec: + group: external-secrets.io + names: + categories: + - externalsecrets + kind: ClusterExternalSecret + listKind: ClusterExternalSecretList + plural: clusterexternalsecrets + shortNames: + - ces + singular: clusterexternalsecret + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .spec.externalSecretSpec.secretStoreRef.name + name: Store + type: string + - jsonPath: .spec.refreshTime + name: Refresh Interval + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: ClusterExternalSecret is the Schema for the clusterexternalsecrets 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: ClusterExternalSecretSpec defines the desired state of ClusterExternalSecret. + properties: + externalSecretMetadata: + description: The metadata of the external secrets to be created + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + externalSecretName: + description: The name of the external secrets to be created defaults to the name of the ClusterExternalSecret + type: string + externalSecretSpec: + description: The spec for the ExternalSecrets to be created + properties: + data: + description: Data defines the connection between the Kubernetes Secret keys and the Provider data + items: + description: ExternalSecretData defines the connection between the Kubernetes Secret key (spec.data.) and the Provider data. + properties: + remoteRef: + description: |- + RemoteRef points to the remote secret and defines + which secret (version/property/..) to fetch. + properties: + conversionStrategy: + default: Default + description: Used to define a conversion Strategy + enum: + - Default + - Unicode + type: string + decodingStrategy: + default: None + description: Used to define a decoding Strategy + enum: + - Auto + - Base64 + - Base64URL + - None + type: string + key: + description: Key is the key used in the Provider, mandatory + type: string + metadataPolicy: + default: None + description: Policy for fetching tags/labels from provider secrets, possible options are Fetch, None. Defaults to None + enum: + - None + - Fetch + type: string + property: + description: Used to select a specific property of the Provider value (if a map), if supported + type: string + version: + description: Used to select a specific version of the Provider value, if supported + type: string + required: + - key + type: object + secretKey: + description: |- + SecretKey defines the key in which the controller stores + the value. This is the key in the Kind=Secret + type: string + sourceRef: + description: |- + SourceRef allows you to override the source + from which the value will pulled from. + maxProperties: 1 + properties: + generatorRef: + description: |- + GeneratorRef points to a generator custom resource. + + Deprecated: The generatorRef is not implemented in .data[]. + this will be removed with v1. + properties: + apiVersion: + default: generators.external-secrets.io/v1alpha1 + description: Specify the apiVersion of the generator resource + type: string + kind: + description: Specify the Kind of the resource, e.g. Password, ACRAccessToken etc. + type: string + name: + description: Specify the name of the generator resource + type: string + required: + - kind + - name + type: object + storeRef: + description: SecretStoreRef defines which SecretStore to fetch the ExternalSecret data. + properties: + kind: + description: |- + Kind of the SecretStore resource (SecretStore or ClusterSecretStore) + Defaults to `SecretStore` + type: string + name: + description: Name of the SecretStore resource + type: string + required: + - name + type: object + type: object + required: + - remoteRef + - secretKey + type: object + type: array + dataFrom: + description: |- + DataFrom is used to fetch all properties from a specific Provider data + If multiple entries are specified, the Secret keys are merged in the specified order + items: + properties: + extract: + description: |- + Used to extract multiple key/value pairs from one secret + Note: Extract does not support sourceRef.Generator or sourceRef.GeneratorRef. + properties: + conversionStrategy: + default: Default + description: Used to define a conversion Strategy + enum: + - Default + - Unicode + type: string + decodingStrategy: + default: None + description: Used to define a decoding Strategy + enum: + - Auto + - Base64 + - Base64URL + - None + type: string + key: + description: Key is the key used in the Provider, mandatory + type: string + metadataPolicy: + default: None + description: Policy for fetching tags/labels from provider secrets, possible options are Fetch, None. Defaults to None + enum: + - None + - Fetch + type: string + property: + description: Used to select a specific property of the Provider value (if a map), if supported + type: string + version: + description: Used to select a specific version of the Provider value, if supported + type: string + required: + - key + type: object + find: + description: |- + Used to find secrets based on tags or regular expressions + Note: Find does not support sourceRef.Generator or sourceRef.GeneratorRef. + properties: + conversionStrategy: + default: Default + description: Used to define a conversion Strategy + enum: + - Default + - Unicode + type: string + decodingStrategy: + default: None + description: Used to define a decoding Strategy + enum: + - Auto + - Base64 + - Base64URL + - None + type: string + name: + description: Finds secrets based on the name. + properties: + regexp: + description: Finds secrets base + type: string + type: object + path: + description: A root path to start the find operations. + type: string + tags: + additionalProperties: + type: string + description: Find secrets based on tags. + type: object + type: object + rewrite: + description: |- + Used to rewrite secret Keys after getting them from the secret Provider + Multiple Rewrite operations can be provided. They are applied in a layered order (first to last) + items: + properties: + regexp: + description: |- + Used to rewrite with regular expressions. + The resulting key will be the output of a regexp.ReplaceAll operation. + properties: + source: + description: Used to define the regular expression of a re.Compiler. + type: string + target: + description: Used to define the target pattern of a ReplaceAll operation. + type: string + required: + - source + - target + type: object + transform: + description: |- + Used to apply string transformation on the secrets. + The resulting key will be the output of the template applied by the operation. + properties: + template: + description: |- + Used to define the template to apply on the secret name. + `.value ` will specify the secret name in the template. + type: string + required: + - template + type: object + type: object + type: array + sourceRef: + description: |- + SourceRef points to a store or generator + which contains secret values ready to use. + Use this in combination with Extract or Find pull values out of + a specific SecretStore. + When sourceRef points to a generator Extract or Find is not supported. + The generator returns a static map of values + maxProperties: 1 + properties: + generatorRef: + description: GeneratorRef points to a generator custom resource. + properties: + apiVersion: + default: generators.external-secrets.io/v1alpha1 + description: Specify the apiVersion of the generator resource + type: string + kind: + description: Specify the Kind of the resource, e.g. Password, ACRAccessToken etc. + type: string + name: + description: Specify the name of the generator resource + type: string + required: + - kind + - name + type: object + storeRef: + description: SecretStoreRef defines which SecretStore to fetch the ExternalSecret data. + properties: + kind: + description: |- + Kind of the SecretStore resource (SecretStore or ClusterSecretStore) + Defaults to `SecretStore` + type: string + name: + description: Name of the SecretStore resource + type: string + required: + - name + type: object + type: object + type: object + type: array + refreshInterval: + default: 1h + description: |- + RefreshInterval is the amount of time before the values are read again from the SecretStore provider + Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h" + May be set to zero to fetch and create it once. Defaults to 1h. + type: string + secretStoreRef: + description: SecretStoreRef defines which SecretStore to fetch the ExternalSecret data. + properties: + kind: + description: |- + Kind of the SecretStore resource (SecretStore or ClusterSecretStore) + Defaults to `SecretStore` + type: string + name: + description: Name of the SecretStore resource + type: string + required: + - name + type: object + target: + default: + creationPolicy: Owner + deletionPolicy: Retain + description: |- + ExternalSecretTarget defines the Kubernetes Secret to be created + There can be only one target per ExternalSecret. + properties: + creationPolicy: + default: Owner + description: |- + CreationPolicy defines rules on how to create the resulting Secret + Defaults to 'Owner' + enum: + - Owner + - Orphan + - Merge + - None + type: string + deletionPolicy: + default: Retain + description: |- + DeletionPolicy defines rules on how to delete the resulting Secret + Defaults to 'Retain' + enum: + - Delete + - Merge + - Retain + type: string + immutable: + description: Immutable defines if the final secret will be immutable + type: boolean + name: + description: |- + Name defines the name of the Secret resource to be managed + This field is immutable + Defaults to the .metadata.name of the ExternalSecret resource + type: string + template: + description: Template defines a blueprint for the created Secret resource. + properties: + data: + additionalProperties: + type: string + type: object + engineVersion: + default: v2 + description: |- + EngineVersion specifies the template engine version + that should be used to compile/execute the + template specified in .data and .templateFrom[]. + enum: + - v1 + - v2 + type: string + mergePolicy: + default: Replace + enum: + - Replace + - Merge + type: string + metadata: + description: ExternalSecretTemplateMetadata defines metadata fields for the Secret blueprint. + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + templateFrom: + items: + properties: + configMap: + properties: + items: + items: + properties: + key: + type: string + templateAs: + default: Values + enum: + - Values + - KeysAndValues + type: string + required: + - key + type: object + type: array + name: + type: string + required: + - items + - name + type: object + literal: + type: string + secret: + properties: + items: + items: + properties: + key: + type: string + templateAs: + default: Values + enum: + - Values + - KeysAndValues + type: string + required: + - key + type: object + type: array + name: + type: string + required: + - items + - name + type: object + target: + default: Data + enum: + - Data + - Annotations + - Labels + type: string + type: object + type: array + type: + type: string + type: object + type: object + type: object + namespaceSelector: + description: |- + The labels to select by to find the Namespaces to create the ExternalSecrets in. + Deprecated: Use NamespaceSelectors instead. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelectors: + description: A list of labels to select by to find the Namespaces to create the ExternalSecrets in. The selectors are ORed. + items: + description: |- + A label selector is a label query over a set of resources. The result of matchLabels and + matchExpressions are ANDed. An empty label selector matches all objects. A null + label selector matches no objects. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: array + namespaces: + description: Choose namespaces by name. This field is ORed with anything that NamespaceSelectors ends up choosing. + items: + type: string + type: array + refreshTime: + description: The time in which the controller should reconcile its objects and recheck namespaces for labels. + type: string + required: + - externalSecretSpec + type: object + status: + description: ClusterExternalSecretStatus defines the observed state of ClusterExternalSecret. + properties: + conditions: + items: + properties: + message: + type: string + status: + type: string + type: + type: string + required: + - status + - type + type: object + type: array + externalSecretName: + description: ExternalSecretName is the name of the ExternalSecrets created by the ClusterExternalSecret + type: string + failedNamespaces: + description: Failed namespaces are the namespaces that failed to apply an ExternalSecret + items: + description: ClusterExternalSecretNamespaceFailure represents a failed namespace deployment and it's reason. + properties: + namespace: + description: Namespace is the namespace that failed when trying to apply an ExternalSecret + type: string + reason: + description: Reason is why the ExternalSecret failed to apply to the namespace + type: string + required: + - namespace + type: object + type: array + provisionedNamespaces: + description: ProvisionedNamespaces are the namespaces where the ClusterExternalSecret has secrets + items: + type: string + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- if .Values.crds.conversion.enabled }} + conversion: + strategy: Webhook + webhook: + conversionReviewVersions: + - v1 + clientConfig: + service: + name: {{ include "external-secrets.fullname" . }}-webhook + namespace: {{ .Release.Namespace | quote }} + path: /convert +{{- end }} +{{- end }} diff --git a/kubernetes-vault/external-secrets/templates/crds/clustersecretstore.yaml b/kubernetes-vault/external-secrets/templates/crds/clustersecretstore.yaml new file mode 100644 index 0000000..8f5aaff --- /dev/null +++ b/kubernetes-vault/external-secrets/templates/crds/clustersecretstore.yaml @@ -0,0 +1,4601 @@ +{{- if and (.Values.installCRDs) (.Values.crds.createClusterSecretStore) }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + {{- with .Values.crds.annotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- if and .Values.crds.conversion.enabled .Values.webhook.certManager.enabled .Values.webhook.certManager.addInjectorAnnotations }} + cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/{{ include "external-secrets.fullname" . }}-webhook + {{- end }} + controller-gen.kubebuilder.io/version: v0.16.2 + labels: + external-secrets.io/component: controller + name: clustersecretstores.external-secrets.io +spec: + group: external-secrets.io + names: + categories: + - externalsecrets + kind: ClusterSecretStore + listKind: ClusterSecretStoreList + plural: clustersecretstores + shortNames: + - css + singular: clustersecretstore + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: AGE + type: date + - jsonPath: .status.conditions[?(@.type=="Ready")].reason + name: Status + type: string + deprecated: true + name: v1alpha1 + schema: + openAPIV3Schema: + description: ClusterSecretStore represents a secure external location for storing secrets, which can be referenced as part of `storeRef` fields. + 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: SecretStoreSpec defines the desired state of SecretStore. + properties: + controller: + description: |- + Used to select the correct ESO controller (think: ingress.ingressClassName) + The ESO controller is instantiated with a specific controller name and filters ES based on this property + type: string + provider: + description: Used to configure the provider. Only one provider may be set + maxProperties: 1 + minProperties: 1 + properties: + akeyless: + description: Akeyless configures this store to sync secrets using Akeyless Vault provider + properties: + akeylessGWApiURL: + description: Akeyless GW API Url from which the secrets to be fetched from. + type: string + authSecretRef: + description: Auth configures how the operator authenticates with Akeyless. + properties: + kubernetesAuth: + description: |- + Kubernetes authenticates with Akeyless by passing the ServiceAccount + token stored in the named Secret resource. + properties: + accessID: + description: the Akeyless Kubernetes auth-method access-id + type: string + k8sConfName: + description: Kubernetes-auth configuration name in Akeyless-Gateway + type: string + secretRef: + description: |- + Optional secret field containing a Kubernetes ServiceAccount JWT used + for authenticating with Akeyless. If a name is specified without a key, + `token` is the default. If one is not specified, the one bound to + the controller will be used. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + serviceAccountRef: + description: |- + Optional service account field containing the name of a kubernetes ServiceAccount. + If the service account is specified, the service account secret token JWT will be used + for authenticating with Akeyless. If the service account selector is not supplied, + the secretRef will be used instead. + properties: + audiences: + description: |- + Audience specifies the `aud` claim for the service account token + If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity + then this audiences will be appended to the list + items: + type: string + type: array + name: + description: The name of the ServiceAccount resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + required: + - name + type: object + required: + - accessID + - k8sConfName + type: object + secretRef: + description: |- + Reference to a Secret that contains the details + to authenticate with Akeyless. + properties: + accessID: + description: The SecretAccessID is used for authentication + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + accessType: + description: |- + A reference to a specific 'key' within a Secret resource, + In some instances, `key` is a required field. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + accessTypeParam: + description: |- + A reference to a specific 'key' within a Secret resource, + In some instances, `key` is a required field. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + type: object + caBundle: + description: |- + PEM/base64 encoded CA bundle used to validate Akeyless Gateway certificate. Only used + if the AkeylessGWApiURL URL is using HTTPS protocol. If not set the system root certificates + are used to validate the TLS connection. + format: byte + type: string + caProvider: + description: The provider for the CA bundle to use to validate Akeyless Gateway certificate. + properties: + key: + description: The key the value inside of the provider type to use, only used with "Secret" type + type: string + name: + description: The name of the object located at the provider type. + type: string + namespace: + description: The namespace the Provider type is in. + type: string + type: + description: The type of provider to use such as "Secret", or "ConfigMap". + enum: + - Secret + - ConfigMap + type: string + required: + - name + - type + type: object + required: + - akeylessGWApiURL + - authSecretRef + type: object + alibaba: + description: Alibaba configures this store to sync secrets using Alibaba Cloud provider + properties: + auth: + description: AlibabaAuth contains a secretRef for credentials. + properties: + rrsa: + description: Authenticate against Alibaba using RRSA. + properties: + oidcProviderArn: + type: string + oidcTokenFilePath: + type: string + roleArn: + type: string + sessionName: + type: string + required: + - oidcProviderArn + - oidcTokenFilePath + - roleArn + - sessionName + type: object + secretRef: + description: AlibabaAuthSecretRef holds secret references for Alibaba credentials. + properties: + accessKeyIDSecretRef: + description: The AccessKeyID is used for authentication + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + accessKeySecretSecretRef: + description: The AccessKeySecret is used for authentication + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + required: + - accessKeyIDSecretRef + - accessKeySecretSecretRef + type: object + type: object + regionID: + description: Alibaba Region to be used for the provider + type: string + required: + - auth + - regionID + type: object + aws: + description: AWS configures this store to sync secrets using AWS Secret Manager provider + properties: + auth: + description: |- + Auth defines the information necessary to authenticate against AWS + if not set aws sdk will infer credentials from your environment + see: https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials + properties: + jwt: + description: Authenticate against AWS using service account tokens. + properties: + serviceAccountRef: + description: A reference to a ServiceAccount resource. + properties: + audiences: + description: |- + Audience specifies the `aud` claim for the service account token + If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity + then this audiences will be appended to the list + items: + type: string + type: array + name: + description: The name of the ServiceAccount resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + required: + - name + type: object + type: object + secretRef: + description: |- + AWSAuthSecretRef holds secret references for AWS credentials + both AccessKeyID and SecretAccessKey must be defined in order to properly authenticate. + properties: + accessKeyIDSecretRef: + description: The AccessKeyID is used for authentication + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + secretAccessKeySecretRef: + description: The SecretAccessKey is used for authentication + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + type: object + region: + description: AWS Region to be used for the provider + type: string + role: + description: Role is a Role ARN which the SecretManager provider will assume + type: string + service: + description: Service defines which service should be used to fetch the secrets + enum: + - SecretsManager + - ParameterStore + type: string + required: + - region + - service + type: object + azurekv: + description: AzureKV configures this store to sync secrets using Azure Key Vault provider + properties: + authSecretRef: + description: Auth configures how the operator authenticates with Azure. Required for ServicePrincipal auth type. + properties: + clientId: + description: The Azure clientId of the service principle used for authentication. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + clientSecret: + description: The Azure ClientSecret of the service principle used for authentication. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + authType: + default: ServicePrincipal + description: |- + Auth type defines how to authenticate to the keyvault service. + Valid values are: + - "ServicePrincipal" (default): Using a service principal (tenantId, clientId, clientSecret) + - "ManagedIdentity": Using Managed Identity assigned to the pod (see aad-pod-identity) + enum: + - ServicePrincipal + - ManagedIdentity + - WorkloadIdentity + type: string + identityId: + description: If multiple Managed Identity is assigned to the pod, you can select the one to be used + type: string + serviceAccountRef: + description: |- + ServiceAccountRef specified the service account + that should be used when authenticating with WorkloadIdentity. + properties: + audiences: + description: |- + Audience specifies the `aud` claim for the service account token + If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity + then this audiences will be appended to the list + items: + type: string + type: array + name: + description: The name of the ServiceAccount resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + required: + - name + type: object + tenantId: + description: TenantID configures the Azure Tenant to send requests to. Required for ServicePrincipal auth type. + type: string + vaultUrl: + description: Vault Url from which the secrets to be fetched from. + type: string + required: + - vaultUrl + type: object + fake: + description: Fake configures a store with static key/value pairs + properties: + data: + items: + properties: + key: + type: string + value: + type: string + valueMap: + additionalProperties: + type: string + type: object + version: + type: string + required: + - key + type: object + type: array + required: + - data + type: object + gcpsm: + description: GCPSM configures this store to sync secrets using Google Cloud Platform Secret Manager provider + properties: + auth: + description: Auth defines the information necessary to authenticate against GCP + properties: + secretRef: + properties: + secretAccessKeySecretRef: + description: The SecretAccessKey is used for authentication + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + workloadIdentity: + properties: + clusterLocation: + type: string + clusterName: + type: string + clusterProjectID: + type: string + serviceAccountRef: + description: A reference to a ServiceAccount resource. + properties: + audiences: + description: |- + Audience specifies the `aud` claim for the service account token + If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity + then this audiences will be appended to the list + items: + type: string + type: array + name: + description: The name of the ServiceAccount resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + required: + - name + type: object + required: + - clusterLocation + - clusterName + - serviceAccountRef + type: object + type: object + projectID: + description: ProjectID project where secret is located + type: string + type: object + gitlab: + description: GitLab configures this store to sync secrets using GitLab Variables provider + properties: + auth: + description: Auth configures how secret-manager authenticates with a GitLab instance. + properties: + SecretRef: + properties: + accessToken: + description: AccessToken is used for authentication. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + required: + - SecretRef + type: object + projectID: + description: ProjectID specifies a project where secrets are located. + type: string + url: + description: URL configures the GitLab instance URL. Defaults to https://gitlab.com/. + type: string + required: + - auth + type: object + ibm: + description: IBM configures this store to sync secrets using IBM Cloud provider + properties: + auth: + description: Auth configures how secret-manager authenticates with the IBM secrets manager. + properties: + secretRef: + properties: + secretApiKeySecretRef: + description: The SecretAccessKey is used for authentication + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + required: + - secretRef + type: object + serviceUrl: + description: ServiceURL is the Endpoint URL that is specific to the Secrets Manager service instance + type: string + required: + - auth + type: object + kubernetes: + description: Kubernetes configures this store to sync secrets using a Kubernetes cluster provider + properties: + auth: + description: Auth configures how secret-manager authenticates with a Kubernetes instance. + maxProperties: 1 + minProperties: 1 + properties: + cert: + description: has both clientCert and clientKey as secretKeySelector + properties: + clientCert: + description: |- + A reference to a specific 'key' within a Secret resource, + In some instances, `key` is a required field. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + clientKey: + description: |- + A reference to a specific 'key' within a Secret resource, + In some instances, `key` is a required field. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + serviceAccount: + description: points to a service account that should be used for authentication + properties: + serviceAccount: + description: A reference to a ServiceAccount resource. + properties: + audiences: + description: |- + Audience specifies the `aud` claim for the service account token + If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity + then this audiences will be appended to the list + items: + type: string + type: array + name: + description: The name of the ServiceAccount resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + required: + - name + type: object + type: object + token: + description: use static token to authenticate with + properties: + bearerToken: + description: |- + A reference to a specific 'key' within a Secret resource, + In some instances, `key` is a required field. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + type: object + remoteNamespace: + default: default + description: Remote namespace to fetch the secrets from + type: string + server: + description: configures the Kubernetes server Address. + properties: + caBundle: + description: CABundle is a base64-encoded CA certificate + format: byte + type: string + caProvider: + description: 'see: https://external-secrets.io/v0.4.1/spec/#external-secrets.io/v1alpha1.CAProvider' + properties: + key: + description: The key the value inside of the provider type to use, only used with "Secret" type + type: string + name: + description: The name of the object located at the provider type. + type: string + namespace: + description: The namespace the Provider type is in. + type: string + type: + description: The type of provider to use such as "Secret", or "ConfigMap". + enum: + - Secret + - ConfigMap + type: string + required: + - name + - type + type: object + url: + default: kubernetes.default + description: configures the Kubernetes server Address. + type: string + type: object + required: + - auth + type: object + oracle: + description: Oracle configures this store to sync secrets using Oracle Vault provider + properties: + auth: + description: |- + Auth configures how secret-manager authenticates with the Oracle Vault. + If empty, instance principal is used. Optionally, the authenticating principal type + and/or user data may be supplied for the use of workload identity and user principal. + properties: + secretRef: + description: SecretRef to pass through sensitive information. + properties: + fingerprint: + description: Fingerprint is the fingerprint of the API private key. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + privatekey: + description: PrivateKey is the user's API Signing Key in PEM format, used for authentication. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + required: + - fingerprint + - privatekey + type: object + tenancy: + description: Tenancy is the tenancy OCID where user is located. + type: string + user: + description: User is an access OCID specific to the account. + type: string + required: + - secretRef + - tenancy + - user + type: object + compartment: + description: |- + Compartment is the vault compartment OCID. + Required for PushSecret + type: string + encryptionKey: + description: |- + EncryptionKey is the OCID of the encryption key within the vault. + Required for PushSecret + type: string + principalType: + description: |- + The type of principal to use for authentication. If left blank, the Auth struct will + determine the principal type. This optional field must be specified if using + workload identity. + enum: + - "" + - UserPrincipal + - InstancePrincipal + - Workload + type: string + region: + description: Region is the region where vault is located. + type: string + serviceAccountRef: + description: |- + ServiceAccountRef specified the service account + that should be used when authenticating with WorkloadIdentity. + properties: + audiences: + description: |- + Audience specifies the `aud` claim for the service account token + If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity + then this audiences will be appended to the list + items: + type: string + type: array + name: + description: The name of the ServiceAccount resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + required: + - name + type: object + vault: + description: Vault is the vault's OCID of the specific vault where secret is located. + type: string + required: + - region + - vault + type: object + passworddepot: + description: Configures a store to sync secrets with a Password Depot instance. + properties: + auth: + description: Auth configures how secret-manager authenticates with a Password Depot instance. + properties: + secretRef: + properties: + credentials: + description: Username / Password is used for authentication. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + required: + - secretRef + type: object + database: + description: Database to use as source + type: string + host: + description: URL configures the Password Depot instance URL. + type: string + required: + - auth + - database + - host + type: object + vault: + description: Vault configures this store to sync secrets using Hashi provider + properties: + auth: + description: Auth configures how secret-manager authenticates with the Vault server. + properties: + appRole: + description: |- + AppRole authenticates with Vault using the App Role auth mechanism, + with the role and secret stored in a Kubernetes Secret resource. + properties: + path: + default: approle + description: |- + Path where the App Role authentication backend is mounted + in Vault, e.g: "approle" + type: string + roleId: + description: |- + RoleID configured in the App Role authentication backend when setting + up the authentication backend in Vault. + type: string + secretRef: + description: |- + Reference to a key in a Secret that contains the App Role secret used + to authenticate with Vault. + The `key` field must be specified and denotes which entry within the Secret + resource is used as the app role secret. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + required: + - path + - roleId + - secretRef + type: object + cert: + description: |- + Cert authenticates with TLS Certificates by passing client certificate, private key and ca certificate + Cert authentication method + properties: + clientCert: + description: |- + ClientCert is a certificate to authenticate using the Cert Vault + authentication method + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + secretRef: + description: |- + SecretRef to a key in a Secret resource containing client private key to + authenticate with Vault using the Cert authentication method + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + jwt: + description: |- + Jwt authenticates with Vault by passing role and JWT token using the + JWT/OIDC authentication method + properties: + kubernetesServiceAccountToken: + description: |- + Optional ServiceAccountToken specifies the Kubernetes service account for which to request + a token for with the `TokenRequest` API. + properties: + audiences: + description: |- + Optional audiences field that will be used to request a temporary Kubernetes service + account token for the service account referenced by `serviceAccountRef`. + Defaults to a single audience `vault` it not specified. + items: + type: string + type: array + expirationSeconds: + description: |- + Optional expiration time in seconds that will be used to request a temporary + Kubernetes service account token for the service account referenced by + `serviceAccountRef`. + Defaults to 10 minutes. + format: int64 + type: integer + serviceAccountRef: + description: Service account field containing the name of a kubernetes ServiceAccount. + properties: + audiences: + description: |- + Audience specifies the `aud` claim for the service account token + If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity + then this audiences will be appended to the list + items: + type: string + type: array + name: + description: The name of the ServiceAccount resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + required: + - name + type: object + required: + - serviceAccountRef + type: object + path: + default: jwt + description: |- + Path where the JWT authentication backend is mounted + in Vault, e.g: "jwt" + type: string + role: + description: |- + Role is a JWT role to authenticate using the JWT/OIDC Vault + authentication method + type: string + secretRef: + description: |- + Optional SecretRef that refers to a key in a Secret resource containing JWT token to + authenticate with Vault using the JWT/OIDC authentication method. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + required: + - path + type: object + kubernetes: + description: |- + Kubernetes authenticates with Vault by passing the ServiceAccount + token stored in the named Secret resource to the Vault server. + properties: + mountPath: + default: kubernetes + description: |- + Path where the Kubernetes authentication backend is mounted in Vault, e.g: + "kubernetes" + type: string + role: + description: |- + A required field containing the Vault Role to assume. A Role binds a + Kubernetes ServiceAccount with a set of Vault policies. + type: string + secretRef: + description: |- + Optional secret field containing a Kubernetes ServiceAccount JWT used + for authenticating with Vault. If a name is specified without a key, + `token` is the default. If one is not specified, the one bound to + the controller will be used. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + serviceAccountRef: + description: |- + Optional service account field containing the name of a kubernetes ServiceAccount. + If the service account is specified, the service account secret token JWT will be used + for authenticating with Vault. If the service account selector is not supplied, + the secretRef will be used instead. + properties: + audiences: + description: |- + Audience specifies the `aud` claim for the service account token + If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity + then this audiences will be appended to the list + items: + type: string + type: array + name: + description: The name of the ServiceAccount resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + required: + - name + type: object + required: + - mountPath + - role + type: object + ldap: + description: |- + Ldap authenticates with Vault by passing username/password pair using + the LDAP authentication method + properties: + path: + default: ldap + description: |- + Path where the LDAP authentication backend is mounted + in Vault, e.g: "ldap" + type: string + secretRef: + description: |- + SecretRef to a key in a Secret resource containing password for the LDAP + user used to authenticate with Vault using the LDAP authentication + method + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + username: + description: |- + Username is a LDAP user name used to authenticate using the LDAP Vault + authentication method + type: string + required: + - path + - username + type: object + tokenSecretRef: + description: TokenSecretRef authenticates with Vault by presenting a token. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + caBundle: + description: |- + PEM encoded CA bundle used to validate Vault server certificate. Only used + if the Server URL is using HTTPS protocol. This parameter is ignored for + plain HTTP protocol connection. If not set the system root certificates + are used to validate the TLS connection. + format: byte + type: string + caProvider: + description: The provider for the CA bundle to use to validate Vault server certificate. + properties: + key: + description: The key the value inside of the provider type to use, only used with "Secret" type + type: string + name: + description: The name of the object located at the provider type. + type: string + namespace: + description: The namespace the Provider type is in. + type: string + type: + description: The type of provider to use such as "Secret", or "ConfigMap". + enum: + - Secret + - ConfigMap + type: string + required: + - name + - type + type: object + forwardInconsistent: + description: |- + ForwardInconsistent tells Vault to forward read-after-write requests to the Vault + leader instead of simply retrying within a loop. This can increase performance if + the option is enabled serverside. + https://www.vaultproject.io/docs/configuration/replication#allow_forwarding_via_header + type: boolean + namespace: + description: |- + Name of the vault namespace. Namespaces is a set of features within Vault Enterprise that allows + Vault environments to support Secure Multi-tenancy. e.g: "ns1". + More about namespaces can be found here https://www.vaultproject.io/docs/enterprise/namespaces + type: string + path: + description: |- + Path is the mount path of the Vault KV backend endpoint, e.g: + "secret". The v2 KV secret engine version specific "/data" path suffix + for fetching secrets from Vault is optional and will be appended + if not present in specified path. + type: string + readYourWrites: + description: |- + ReadYourWrites ensures isolated read-after-write semantics by + providing discovered cluster replication states in each request. + More information about eventual consistency in Vault can be found here + https://www.vaultproject.io/docs/enterprise/consistency + type: boolean + server: + description: 'Server is the connection address for the Vault server, e.g: "https://vault.example.com:8200".' + type: string + version: + default: v2 + description: |- + Version is the Vault KV secret engine version. This can be either "v1" or + "v2". Version defaults to "v2". + enum: + - v1 + - v2 + type: string + required: + - auth + - server + type: object + webhook: + description: Webhook configures this store to sync secrets using a generic templated webhook + properties: + body: + description: Body + type: string + caBundle: + description: |- + PEM encoded CA bundle used to validate webhook server certificate. Only used + if the Server URL is using HTTPS protocol. This parameter is ignored for + plain HTTP protocol connection. If not set the system root certificates + are used to validate the TLS connection. + format: byte + type: string + caProvider: + description: The provider for the CA bundle to use to validate webhook server certificate. + properties: + key: + description: The key the value inside of the provider type to use, only used with "Secret" type + type: string + name: + description: The name of the object located at the provider type. + type: string + namespace: + description: The namespace the Provider type is in. + type: string + type: + description: The type of provider to use such as "Secret", or "ConfigMap". + enum: + - Secret + - ConfigMap + type: string + required: + - name + - type + type: object + headers: + additionalProperties: + type: string + description: Headers + type: object + method: + description: Webhook Method + type: string + result: + description: Result formatting + properties: + jsonPath: + description: Json path of return value + type: string + type: object + secrets: + description: |- + Secrets to fill in templates + These secrets will be passed to the templating function as key value pairs under the given name + items: + properties: + name: + description: Name of this secret in templates + type: string + secretRef: + description: Secret ref to fill in credentials + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + required: + - name + - secretRef + type: object + type: array + timeout: + description: Timeout + type: string + url: + description: Webhook url to call + type: string + required: + - result + - url + type: object + yandexlockbox: + description: YandexLockbox configures this store to sync secrets using Yandex Lockbox provider + properties: + apiEndpoint: + description: Yandex.Cloud API endpoint (e.g. 'api.cloud.yandex.net:443') + type: string + auth: + description: Auth defines the information necessary to authenticate against Yandex Lockbox + properties: + authorizedKeySecretRef: + description: The authorized key used for authentication + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + caProvider: + description: The provider for the CA bundle to use to validate Yandex.Cloud server certificate. + properties: + certSecretRef: + description: |- + A reference to a specific 'key' within a Secret resource, + In some instances, `key` is a required field. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + required: + - auth + type: object + type: object + retrySettings: + description: Used to configure http retries if failed + properties: + maxRetries: + format: int32 + type: integer + retryInterval: + type: string + type: object + required: + - provider + type: object + status: + description: SecretStoreStatus defines the observed state of the SecretStore. + properties: + conditions: + items: + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + required: + - status + - type + type: object + type: array + type: object + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: AGE + type: date + - jsonPath: .status.conditions[?(@.type=="Ready")].reason + name: Status + type: string + - jsonPath: .status.capabilities + name: Capabilities + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: ClusterSecretStore represents a secure external location for storing secrets, which can be referenced as part of `storeRef` fields. + 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: SecretStoreSpec defines the desired state of SecretStore. + properties: + conditions: + description: Used to constraint a ClusterSecretStore to specific namespaces. Relevant only to ClusterSecretStore + items: + description: |- + ClusterSecretStoreCondition describes a condition by which to choose namespaces to process ExternalSecrets in + for a ClusterSecretStore instance. + properties: + namespaceRegexes: + description: Choose namespaces by using regex matching + items: + type: string + type: array + namespaceSelector: + description: Choose namespace using a labelSelector + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Choose namespaces by name + items: + type: string + type: array + type: object + type: array + controller: + description: |- + Used to select the correct ESO controller (think: ingress.ingressClassName) + The ESO controller is instantiated with a specific controller name and filters ES based on this property + type: string + provider: + description: Used to configure the provider. Only one provider may be set + maxProperties: 1 + minProperties: 1 + properties: + akeyless: + description: Akeyless configures this store to sync secrets using Akeyless Vault provider + properties: + akeylessGWApiURL: + description: Akeyless GW API Url from which the secrets to be fetched from. + type: string + authSecretRef: + description: Auth configures how the operator authenticates with Akeyless. + properties: + kubernetesAuth: + description: |- + Kubernetes authenticates with Akeyless by passing the ServiceAccount + token stored in the named Secret resource. + properties: + accessID: + description: the Akeyless Kubernetes auth-method access-id + type: string + k8sConfName: + description: Kubernetes-auth configuration name in Akeyless-Gateway + type: string + secretRef: + description: |- + Optional secret field containing a Kubernetes ServiceAccount JWT used + for authenticating with Akeyless. If a name is specified without a key, + `token` is the default. If one is not specified, the one bound to + the controller will be used. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + serviceAccountRef: + description: |- + Optional service account field containing the name of a kubernetes ServiceAccount. + If the service account is specified, the service account secret token JWT will be used + for authenticating with Akeyless. If the service account selector is not supplied, + the secretRef will be used instead. + properties: + audiences: + description: |- + Audience specifies the `aud` claim for the service account token + If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity + then this audiences will be appended to the list + items: + type: string + type: array + name: + description: The name of the ServiceAccount resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + required: + - name + type: object + required: + - accessID + - k8sConfName + type: object + secretRef: + description: |- + Reference to a Secret that contains the details + to authenticate with Akeyless. + properties: + accessID: + description: The SecretAccessID is used for authentication + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + accessType: + description: |- + A reference to a specific 'key' within a Secret resource, + In some instances, `key` is a required field. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + accessTypeParam: + description: |- + A reference to a specific 'key' within a Secret resource, + In some instances, `key` is a required field. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + type: object + caBundle: + description: |- + PEM/base64 encoded CA bundle used to validate Akeyless Gateway certificate. Only used + if the AkeylessGWApiURL URL is using HTTPS protocol. If not set the system root certificates + are used to validate the TLS connection. + format: byte + type: string + caProvider: + description: The provider for the CA bundle to use to validate Akeyless Gateway certificate. + properties: + key: + description: The key where the CA certificate can be found in the Secret or ConfigMap. + type: string + name: + description: The name of the object located at the provider type. + type: string + namespace: + description: |- + The namespace the Provider type is in. + Can only be defined when used in a ClusterSecretStore. + type: string + type: + description: The type of provider to use such as "Secret", or "ConfigMap". + enum: + - Secret + - ConfigMap + type: string + required: + - name + - type + type: object + required: + - akeylessGWApiURL + - authSecretRef + type: object + alibaba: + description: Alibaba configures this store to sync secrets using Alibaba Cloud provider + properties: + auth: + description: AlibabaAuth contains a secretRef for credentials. + properties: + rrsa: + description: Authenticate against Alibaba using RRSA. + properties: + oidcProviderArn: + type: string + oidcTokenFilePath: + type: string + roleArn: + type: string + sessionName: + type: string + required: + - oidcProviderArn + - oidcTokenFilePath + - roleArn + - sessionName + type: object + secretRef: + description: AlibabaAuthSecretRef holds secret references for Alibaba credentials. + properties: + accessKeyIDSecretRef: + description: The AccessKeyID is used for authentication + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + accessKeySecretSecretRef: + description: The AccessKeySecret is used for authentication + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + required: + - accessKeyIDSecretRef + - accessKeySecretSecretRef + type: object + type: object + regionID: + description: Alibaba Region to be used for the provider + type: string + required: + - auth + - regionID + type: object + aws: + description: AWS configures this store to sync secrets using AWS Secret Manager provider + properties: + additionalRoles: + description: AdditionalRoles is a chained list of Role ARNs which the provider will sequentially assume before assuming the Role + items: + type: string + type: array + auth: + description: |- + Auth defines the information necessary to authenticate against AWS + if not set aws sdk will infer credentials from your environment + see: https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials + properties: + jwt: + description: Authenticate against AWS using service account tokens. + properties: + serviceAccountRef: + description: A reference to a ServiceAccount resource. + properties: + audiences: + description: |- + Audience specifies the `aud` claim for the service account token + If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity + then this audiences will be appended to the list + items: + type: string + type: array + name: + description: The name of the ServiceAccount resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + required: + - name + type: object + type: object + secretRef: + description: |- + AWSAuthSecretRef holds secret references for AWS credentials + both AccessKeyID and SecretAccessKey must be defined in order to properly authenticate. + properties: + accessKeyIDSecretRef: + description: The AccessKeyID is used for authentication + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + secretAccessKeySecretRef: + description: The SecretAccessKey is used for authentication + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + sessionTokenSecretRef: + description: |- + The SessionToken used for authentication + This must be defined if AccessKeyID and SecretAccessKey are temporary credentials + see: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + type: object + externalID: + description: AWS External ID set on assumed IAM roles + type: string + prefix: + description: Prefix adds a prefix to all retrieved values. + type: string + region: + description: AWS Region to be used for the provider + type: string + role: + description: Role is a Role ARN which the provider will assume + type: string + secretsManager: + description: SecretsManager defines how the provider behaves when interacting with AWS SecretsManager + properties: + forceDeleteWithoutRecovery: + description: |- + Specifies whether to delete the secret without any recovery window. You + can't use both this parameter and RecoveryWindowInDays in the same call. + If you don't use either, then by default Secrets Manager uses a 30 day + recovery window. + see: https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_DeleteSecret.html#SecretsManager-DeleteSecret-request-ForceDeleteWithoutRecovery + type: boolean + recoveryWindowInDays: + description: |- + The number of days from 7 to 30 that Secrets Manager waits before + permanently deleting the secret. You can't use both this parameter and + ForceDeleteWithoutRecovery in the same call. If you don't use either, + then by default Secrets Manager uses a 30 day recovery window. + see: https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_DeleteSecret.html#SecretsManager-DeleteSecret-request-RecoveryWindowInDays + format: int64 + type: integer + type: object + service: + description: Service defines which service should be used to fetch the secrets + enum: + - SecretsManager + - ParameterStore + type: string + sessionTags: + description: AWS STS assume role session tags + items: + properties: + key: + type: string + value: + type: string + required: + - key + - value + type: object + type: array + transitiveTagKeys: + description: AWS STS assume role transitive session tags. Required when multiple rules are used with the provider + items: + type: string + type: array + required: + - region + - service + type: object + azurekv: + description: AzureKV configures this store to sync secrets using Azure Key Vault provider + properties: + authSecretRef: + description: Auth configures how the operator authenticates with Azure. Required for ServicePrincipal auth type. Optional for WorkloadIdentity. + properties: + clientCertificate: + description: The Azure ClientCertificate of the service principle used for authentication. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + clientId: + description: The Azure clientId of the service principle or managed identity used for authentication. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + clientSecret: + description: The Azure ClientSecret of the service principle used for authentication. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + tenantId: + description: The Azure tenantId of the managed identity used for authentication. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + authType: + default: ServicePrincipal + description: |- + Auth type defines how to authenticate to the keyvault service. + Valid values are: + - "ServicePrincipal" (default): Using a service principal (tenantId, clientId, clientSecret) + - "ManagedIdentity": Using Managed Identity assigned to the pod (see aad-pod-identity) + enum: + - ServicePrincipal + - ManagedIdentity + - WorkloadIdentity + type: string + environmentType: + default: PublicCloud + description: |- + EnvironmentType specifies the Azure cloud environment endpoints to use for + connecting and authenticating with Azure. By default it points to the public cloud AAD endpoint. + The following endpoints are available, also see here: https://github.com/Azure/go-autorest/blob/main/autorest/azure/environments.go#L152 + PublicCloud, USGovernmentCloud, ChinaCloud, GermanCloud + enum: + - PublicCloud + - USGovernmentCloud + - ChinaCloud + - GermanCloud + type: string + identityId: + description: If multiple Managed Identity is assigned to the pod, you can select the one to be used + type: string + serviceAccountRef: + description: |- + ServiceAccountRef specified the service account + that should be used when authenticating with WorkloadIdentity. + properties: + audiences: + description: |- + Audience specifies the `aud` claim for the service account token + If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity + then this audiences will be appended to the list + items: + type: string + type: array + name: + description: The name of the ServiceAccount resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + required: + - name + type: object + tenantId: + description: TenantID configures the Azure Tenant to send requests to. Required for ServicePrincipal auth type. Optional for WorkloadIdentity. + type: string + vaultUrl: + description: Vault Url from which the secrets to be fetched from. + type: string + required: + - vaultUrl + type: object + beyondtrust: + description: Beyondtrust configures this store to sync secrets using Password Safe provider. + properties: + auth: + description: Auth configures how the operator authenticates with Beyondtrust. + properties: + certificate: + description: Content of the certificate (cert.pem) for use when authenticating with an OAuth client Id using a Client Certificate. + properties: + secretRef: + description: SecretRef references a key in a secret that will be used as value. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + value: + description: Value can be specified directly to set a value without using a secret. + type: string + type: object + certificateKey: + description: Certificate private key (key.pem). For use when authenticating with an OAuth client Id + properties: + secretRef: + description: SecretRef references a key in a secret that will be used as value. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + value: + description: Value can be specified directly to set a value without using a secret. + type: string + type: object + clientId: + properties: + secretRef: + description: SecretRef references a key in a secret that will be used as value. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + value: + description: Value can be specified directly to set a value without using a secret. + type: string + type: object + clientSecret: + properties: + secretRef: + description: SecretRef references a key in a secret that will be used as value. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + value: + description: Value can be specified directly to set a value without using a secret. + type: string + type: object + required: + - clientId + - clientSecret + type: object + server: + description: Auth configures how API server works. + properties: + apiUrl: + type: string + clientTimeOutSeconds: + description: Timeout specifies a time limit for requests made by this Client. The timeout includes connection time, any redirects, and reading the response body. Defaults to 45 seconds. + type: integer + retrievalType: + description: The secret retrieval type. SECRET = Secrets Safe (credential, text, file). MANAGED_ACCOUNT = Password Safe account associated with a system. + type: string + separator: + description: A character that separates the folder names. + type: string + verifyCA: + type: boolean + required: + - apiUrl + - verifyCA + type: object + required: + - auth + - server + type: object + bitwardensecretsmanager: + description: BitwardenSecretsManager configures this store to sync secrets using BitwardenSecretsManager provider + properties: + apiURL: + type: string + auth: + description: |- + Auth configures how secret-manager authenticates with a bitwarden machine account instance. + Make sure that the token being used has permissions on the given secret. + properties: + secretRef: + description: BitwardenSecretsManagerSecretRef contains the credential ref to the bitwarden instance. + properties: + credentials: + description: AccessToken used for the bitwarden instance. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + required: + - credentials + type: object + required: + - secretRef + type: object + bitwardenServerSDKURL: + type: string + caBundle: + description: |- + Base64 encoded certificate for the bitwarden server sdk. The sdk MUST run with HTTPS to make sure no MITM attack + can be performed. + type: string + caProvider: + description: 'see: https://external-secrets.io/latest/spec/#external-secrets.io/v1alpha1.CAProvider' + properties: + key: + description: The key where the CA certificate can be found in the Secret or ConfigMap. + type: string + name: + description: The name of the object located at the provider type. + type: string + namespace: + description: |- + The namespace the Provider type is in. + Can only be defined when used in a ClusterSecretStore. + type: string + type: + description: The type of provider to use such as "Secret", or "ConfigMap". + enum: + - Secret + - ConfigMap + type: string + required: + - name + - type + type: object + identityURL: + type: string + organizationID: + description: OrganizationID determines which organization this secret store manages. + type: string + projectID: + description: ProjectID determines which project this secret store manages. + type: string + required: + - auth + - organizationID + - projectID + type: object + chef: + description: Chef configures this store to sync secrets with chef server + properties: + auth: + description: Auth defines the information necessary to authenticate against chef Server + properties: + secretRef: + description: ChefAuthSecretRef holds secret references for chef server login credentials. + properties: + privateKeySecretRef: + description: SecretKey is the Signing Key in PEM format, used for authentication. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + required: + - privateKeySecretRef + type: object + required: + - secretRef + type: object + serverUrl: + description: ServerURL is the chef server URL used to connect to. If using orgs you should include your org in the url and terminate the url with a "/" + type: string + username: + description: UserName should be the user ID on the chef server + type: string + required: + - auth + - serverUrl + - username + type: object + conjur: + description: Conjur configures this store to sync secrets using conjur provider + properties: + auth: + properties: + apikey: + properties: + account: + type: string + apiKeyRef: + description: |- + A reference to a specific 'key' within a Secret resource, + In some instances, `key` is a required field. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + userRef: + description: |- + A reference to a specific 'key' within a Secret resource, + In some instances, `key` is a required field. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + required: + - account + - apiKeyRef + - userRef + type: object + jwt: + properties: + account: + type: string + hostId: + description: |- + Optional HostID for JWT authentication. This may be used depending + on how the Conjur JWT authenticator policy is configured. + type: string + secretRef: + description: |- + Optional SecretRef that refers to a key in a Secret resource containing JWT token to + authenticate with Conjur using the JWT authentication method. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + serviceAccountRef: + description: |- + Optional ServiceAccountRef specifies the Kubernetes service account for which to request + a token for with the `TokenRequest` API. + properties: + audiences: + description: |- + Audience specifies the `aud` claim for the service account token + If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity + then this audiences will be appended to the list + items: + type: string + type: array + name: + description: The name of the ServiceAccount resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + required: + - name + type: object + serviceID: + description: The conjur authn jwt webservice id + type: string + required: + - account + - serviceID + type: object + type: object + caBundle: + type: string + caProvider: + description: |- + Used to provide custom certificate authority (CA) certificates + for a secret store. The CAProvider points to a Secret or ConfigMap resource + that contains a PEM-encoded certificate. + properties: + key: + description: The key where the CA certificate can be found in the Secret or ConfigMap. + type: string + name: + description: The name of the object located at the provider type. + type: string + namespace: + description: |- + The namespace the Provider type is in. + Can only be defined when used in a ClusterSecretStore. + type: string + type: + description: The type of provider to use such as "Secret", or "ConfigMap". + enum: + - Secret + - ConfigMap + type: string + required: + - name + - type + type: object + url: + type: string + required: + - auth + - url + type: object + delinea: + description: |- + Delinea DevOps Secrets Vault + https://docs.delinea.com/online-help/products/devops-secrets-vault/current + properties: + clientId: + description: ClientID is the non-secret part of the credential. + properties: + secretRef: + description: SecretRef references a key in a secret that will be used as value. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + value: + description: Value can be specified directly to set a value without using a secret. + type: string + type: object + clientSecret: + description: ClientSecret is the secret part of the credential. + properties: + secretRef: + description: SecretRef references a key in a secret that will be used as value. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + value: + description: Value can be specified directly to set a value without using a secret. + type: string + type: object + tenant: + description: Tenant is the chosen hostname / site name. + type: string + tld: + description: |- + TLD is based on the server location that was chosen during provisioning. + If unset, defaults to "com". + type: string + urlTemplate: + description: |- + URLTemplate + If unset, defaults to "https://%s.secretsvaultcloud.%s/v1/%s%s". + type: string + required: + - clientId + - clientSecret + - tenant + type: object + device42: + description: Device42 configures this store to sync secrets using the Device42 provider + properties: + auth: + description: Auth configures how secret-manager authenticates with a Device42 instance. + properties: + secretRef: + properties: + credentials: + description: Username / Password is used for authentication. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + required: + - secretRef + type: object + host: + description: URL configures the Device42 instance URL. + type: string + required: + - auth + - host + type: object + doppler: + description: Doppler configures this store to sync secrets using the Doppler provider + properties: + auth: + description: Auth configures how the Operator authenticates with the Doppler API + properties: + secretRef: + properties: + dopplerToken: + description: |- + The DopplerToken is used for authentication. + See https://docs.doppler.com/reference/api#authentication for auth token types. + The Key attribute defaults to dopplerToken if not specified. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + required: + - dopplerToken + type: object + required: + - secretRef + type: object + config: + description: Doppler config (required if not using a Service Token) + type: string + format: + description: Format enables the downloading of secrets as a file (string) + enum: + - json + - dotnet-json + - env + - yaml + - docker + type: string + nameTransformer: + description: Environment variable compatible name transforms that change secret names to a different format + enum: + - upper-camel + - camel + - lower-snake + - tf-var + - dotnet-env + - lower-kebab + type: string + project: + description: Doppler project (required if not using a Service Token) + type: string + required: + - auth + type: object + fake: + description: Fake configures a store with static key/value pairs + properties: + data: + items: + properties: + key: + type: string + value: + type: string + valueMap: + additionalProperties: + type: string + description: 'Deprecated: ValueMap is deprecated and is intended to be removed in the future, use the `value` field instead.' + type: object + version: + type: string + required: + - key + type: object + type: array + required: + - data + type: object + fortanix: + description: Fortanix configures this store to sync secrets using the Fortanix provider + properties: + apiKey: + description: APIKey is the API token to access SDKMS Applications. + properties: + secretRef: + description: SecretRef is a reference to a secret containing the SDKMS API Key. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + apiUrl: + description: APIURL is the URL of SDKMS API. Defaults to `sdkms.fortanix.com`. + type: string + type: object + gcpsm: + description: GCPSM configures this store to sync secrets using Google Cloud Platform Secret Manager provider + properties: + auth: + description: Auth defines the information necessary to authenticate against GCP + properties: + secretRef: + properties: + secretAccessKeySecretRef: + description: The SecretAccessKey is used for authentication + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + workloadIdentity: + properties: + clusterLocation: + type: string + clusterName: + type: string + clusterProjectID: + type: string + serviceAccountRef: + description: A reference to a ServiceAccount resource. + properties: + audiences: + description: |- + Audience specifies the `aud` claim for the service account token + If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity + then this audiences will be appended to the list + items: + type: string + type: array + name: + description: The name of the ServiceAccount resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + required: + - name + type: object + required: + - clusterLocation + - clusterName + - serviceAccountRef + type: object + type: object + location: + description: Location optionally defines a location for a secret + type: string + projectID: + description: ProjectID project where secret is located + type: string + type: object + gitlab: + description: GitLab configures this store to sync secrets using GitLab Variables provider + properties: + auth: + description: Auth configures how secret-manager authenticates with a GitLab instance. + properties: + SecretRef: + properties: + accessToken: + description: AccessToken is used for authentication. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + required: + - SecretRef + type: object + environment: + description: Environment environment_scope of gitlab CI/CD variables (Please see https://docs.gitlab.com/ee/ci/environments/#create-a-static-environment on how to create environments) + type: string + groupIDs: + description: GroupIDs specify, which gitlab groups to pull secrets from. Group secrets are read from left to right followed by the project variables. + items: + type: string + type: array + inheritFromGroups: + description: InheritFromGroups specifies whether parent groups should be discovered and checked for secrets. + type: boolean + projectID: + description: ProjectID specifies a project where secrets are located. + type: string + url: + description: URL configures the GitLab instance URL. Defaults to https://gitlab.com/. + type: string + required: + - auth + type: object + ibm: + description: IBM configures this store to sync secrets using IBM Cloud provider + properties: + auth: + description: Auth configures how secret-manager authenticates with the IBM secrets manager. + maxProperties: 1 + minProperties: 1 + properties: + containerAuth: + description: IBM Container-based auth with IAM Trusted Profile. + properties: + iamEndpoint: + type: string + profile: + description: the IBM Trusted Profile + type: string + tokenLocation: + description: Location the token is mounted on the pod + type: string + required: + - profile + type: object + secretRef: + properties: + secretApiKeySecretRef: + description: The SecretAccessKey is used for authentication + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + type: object + serviceUrl: + description: ServiceURL is the Endpoint URL that is specific to the Secrets Manager service instance + type: string + required: + - auth + type: object + infisical: + description: Infisical configures this store to sync secrets using the Infisical provider + properties: + auth: + description: Auth configures how the Operator authenticates with the Infisical API + properties: + universalAuthCredentials: + properties: + clientId: + description: |- + A reference to a specific 'key' within a Secret resource, + In some instances, `key` is a required field. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + clientSecret: + description: |- + A reference to a specific 'key' within a Secret resource, + In some instances, `key` is a required field. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + required: + - clientId + - clientSecret + type: object + type: object + hostAPI: + default: https://app.infisical.com/api + type: string + secretsScope: + properties: + environmentSlug: + type: string + projectSlug: + type: string + secretsPath: + default: / + type: string + required: + - environmentSlug + - projectSlug + type: object + required: + - auth + - secretsScope + type: object + keepersecurity: + description: KeeperSecurity configures this store to sync secrets using the KeeperSecurity provider + properties: + authRef: + description: |- + A reference to a specific 'key' within a Secret resource, + In some instances, `key` is a required field. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + folderID: + type: string + required: + - authRef + - folderID + type: object + kubernetes: + description: Kubernetes configures this store to sync secrets using a Kubernetes cluster provider + properties: + auth: + description: Auth configures how secret-manager authenticates with a Kubernetes instance. + maxProperties: 1 + minProperties: 1 + properties: + cert: + description: has both clientCert and clientKey as secretKeySelector + properties: + clientCert: + description: |- + A reference to a specific 'key' within a Secret resource, + In some instances, `key` is a required field. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + clientKey: + description: |- + A reference to a specific 'key' within a Secret resource, + In some instances, `key` is a required field. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + serviceAccount: + description: points to a service account that should be used for authentication + properties: + audiences: + description: |- + Audience specifies the `aud` claim for the service account token + If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity + then this audiences will be appended to the list + items: + type: string + type: array + name: + description: The name of the ServiceAccount resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + required: + - name + type: object + token: + description: use static token to authenticate with + properties: + bearerToken: + description: |- + A reference to a specific 'key' within a Secret resource, + In some instances, `key` is a required field. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + type: object + authRef: + description: A reference to a secret that contains the auth information. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + remoteNamespace: + default: default + description: Remote namespace to fetch the secrets from + type: string + server: + description: configures the Kubernetes server Address. + properties: + caBundle: + description: CABundle is a base64-encoded CA certificate + format: byte + type: string + caProvider: + description: 'see: https://external-secrets.io/v0.4.1/spec/#external-secrets.io/v1alpha1.CAProvider' + properties: + key: + description: The key where the CA certificate can be found in the Secret or ConfigMap. + type: string + name: + description: The name of the object located at the provider type. + type: string + namespace: + description: |- + The namespace the Provider type is in. + Can only be defined when used in a ClusterSecretStore. + type: string + type: + description: The type of provider to use such as "Secret", or "ConfigMap". + enum: + - Secret + - ConfigMap + type: string + required: + - name + - type + type: object + url: + default: kubernetes.default + description: configures the Kubernetes server Address. + type: string + type: object + type: object + onboardbase: + description: Onboardbase configures this store to sync secrets using the Onboardbase provider + properties: + apiHost: + default: https://public.onboardbase.com/api/v1/ + description: APIHost use this to configure the host url for the API for selfhosted installation, default is https://public.onboardbase.com/api/v1/ + type: string + auth: + description: Auth configures how the Operator authenticates with the Onboardbase API + properties: + apiKeyRef: + description: |- + OnboardbaseAPIKey is the APIKey generated by an admin account. + It is used to recognize and authorize access to a project and environment within onboardbase + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + passcodeRef: + description: OnboardbasePasscode is the passcode attached to the API Key + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + required: + - apiKeyRef + - passcodeRef + type: object + environment: + default: development + description: Environment is the name of an environmnent within a project to pull the secrets from + type: string + project: + default: development + description: Project is an onboardbase project that the secrets should be pulled from + type: string + required: + - apiHost + - auth + - environment + - project + type: object + onepassword: + description: OnePassword configures this store to sync secrets using the 1Password Cloud provider + properties: + auth: + description: Auth defines the information necessary to authenticate against OnePassword Connect Server + properties: + secretRef: + description: OnePasswordAuthSecretRef holds secret references for 1Password credentials. + properties: + connectTokenSecretRef: + description: The ConnectToken is used for authentication to a 1Password Connect Server. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + required: + - connectTokenSecretRef + type: object + required: + - secretRef + type: object + connectHost: + description: ConnectHost defines the OnePassword Connect Server to connect to + type: string + vaults: + additionalProperties: + type: integer + description: Vaults defines which OnePassword vaults to search in which order + type: object + required: + - auth + - connectHost + - vaults + type: object + oracle: + description: Oracle configures this store to sync secrets using Oracle Vault provider + properties: + auth: + description: |- + Auth configures how secret-manager authenticates with the Oracle Vault. + If empty, use the instance principal, otherwise the user credentials specified in Auth. + properties: + secretRef: + description: SecretRef to pass through sensitive information. + properties: + fingerprint: + description: Fingerprint is the fingerprint of the API private key. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + privatekey: + description: PrivateKey is the user's API Signing Key in PEM format, used for authentication. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + required: + - fingerprint + - privatekey + type: object + tenancy: + description: Tenancy is the tenancy OCID where user is located. + type: string + user: + description: User is an access OCID specific to the account. + type: string + required: + - secretRef + - tenancy + - user + type: object + compartment: + description: |- + Compartment is the vault compartment OCID. + Required for PushSecret + type: string + encryptionKey: + description: |- + EncryptionKey is the OCID of the encryption key within the vault. + Required for PushSecret + type: string + principalType: + description: |- + The type of principal to use for authentication. If left blank, the Auth struct will + determine the principal type. This optional field must be specified if using + workload identity. + enum: + - "" + - UserPrincipal + - InstancePrincipal + - Workload + type: string + region: + description: Region is the region where vault is located. + type: string + serviceAccountRef: + description: |- + ServiceAccountRef specified the service account + that should be used when authenticating with WorkloadIdentity. + properties: + audiences: + description: |- + Audience specifies the `aud` claim for the service account token + If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity + then this audiences will be appended to the list + items: + type: string + type: array + name: + description: The name of the ServiceAccount resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + required: + - name + type: object + vault: + description: Vault is the vault's OCID of the specific vault where secret is located. + type: string + required: + - region + - vault + type: object + passbolt: + properties: + auth: + description: Auth defines the information necessary to authenticate against Passbolt Server + properties: + passwordSecretRef: + description: |- + A reference to a specific 'key' within a Secret resource, + In some instances, `key` is a required field. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + privateKeySecretRef: + description: |- + A reference to a specific 'key' within a Secret resource, + In some instances, `key` is a required field. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + required: + - passwordSecretRef + - privateKeySecretRef + type: object + host: + description: Host defines the Passbolt Server to connect to + type: string + required: + - auth + - host + type: object + passworddepot: + description: Configures a store to sync secrets with a Password Depot instance. + properties: + auth: + description: Auth configures how secret-manager authenticates with a Password Depot instance. + properties: + secretRef: + properties: + credentials: + description: Username / Password is used for authentication. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + required: + - secretRef + type: object + database: + description: Database to use as source + type: string + host: + description: URL configures the Password Depot instance URL. + type: string + required: + - auth + - database + - host + type: object + pulumi: + description: Pulumi configures this store to sync secrets using the Pulumi provider + properties: + accessToken: + description: AccessToken is the access tokens to sign in to the Pulumi Cloud Console. + properties: + secretRef: + description: SecretRef is a reference to a secret containing the Pulumi API token. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + apiUrl: + default: https://api.pulumi.com/api/preview + description: APIURL is the URL of the Pulumi API. + type: string + environment: + description: |- + Environment are YAML documents composed of static key-value pairs, programmatic expressions, + dynamically retrieved values from supported providers including all major clouds, + and other Pulumi ESC environments. + To create a new environment, visit https://www.pulumi.com/docs/esc/environments/ for more information. + type: string + organization: + description: |- + Organization are a space to collaborate on shared projects and stacks. + To create a new organization, visit https://app.pulumi.com/ and click "New Organization". + type: string + required: + - accessToken + - environment + - organization + type: object + scaleway: + description: Scaleway + properties: + accessKey: + description: AccessKey is the non-secret part of the api key. + properties: + secretRef: + description: SecretRef references a key in a secret that will be used as value. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + value: + description: Value can be specified directly to set a value without using a secret. + type: string + type: object + apiUrl: + description: APIURL is the url of the api to use. Defaults to https://api.scaleway.com + type: string + projectId: + description: 'ProjectID is the id of your project, which you can find in the console: https://console.scaleway.com/project/settings' + type: string + region: + description: 'Region where your secrets are located: https://developers.scaleway.com/en/quickstart/#region-and-zone' + type: string + secretKey: + description: SecretKey is the non-secret part of the api key. + properties: + secretRef: + description: SecretRef references a key in a secret that will be used as value. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + value: + description: Value can be specified directly to set a value without using a secret. + type: string + type: object + required: + - accessKey + - projectId + - region + - secretKey + type: object + secretserver: + description: |- + SecretServer configures this store to sync secrets using SecretServer provider + https://docs.delinea.com/online-help/secret-server/start.htm + properties: + password: + description: Password is the secret server account password. + properties: + secretRef: + description: SecretRef references a key in a secret that will be used as value. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + value: + description: Value can be specified directly to set a value without using a secret. + type: string + type: object + serverURL: + description: |- + ServerURL + URL to your secret server installation + type: string + username: + description: Username is the secret server account username. + properties: + secretRef: + description: SecretRef references a key in a secret that will be used as value. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + value: + description: Value can be specified directly to set a value without using a secret. + type: string + type: object + required: + - password + - serverURL + - username + type: object + senhasegura: + description: Senhasegura configures this store to sync secrets using senhasegura provider + properties: + auth: + description: Auth defines parameters to authenticate in senhasegura + properties: + clientId: + type: string + clientSecretSecretRef: + description: |- + A reference to a specific 'key' within a Secret resource, + In some instances, `key` is a required field. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + required: + - clientId + - clientSecretSecretRef + type: object + ignoreSslCertificate: + default: false + description: IgnoreSslCertificate defines if SSL certificate must be ignored + type: boolean + module: + description: Module defines which senhasegura module should be used to get secrets + type: string + url: + description: URL of senhasegura + type: string + required: + - auth + - module + - url + type: object + vault: + description: Vault configures this store to sync secrets using Hashi provider + properties: + auth: + description: Auth configures how secret-manager authenticates with the Vault server. + properties: + appRole: + description: |- + AppRole authenticates with Vault using the App Role auth mechanism, + with the role and secret stored in a Kubernetes Secret resource. + properties: + path: + default: approle + description: |- + Path where the App Role authentication backend is mounted + in Vault, e.g: "approle" + type: string + roleId: + description: |- + RoleID configured in the App Role authentication backend when setting + up the authentication backend in Vault. + type: string + roleRef: + description: |- + Reference to a key in a Secret that contains the App Role ID used + to authenticate with Vault. + The `key` field must be specified and denotes which entry within the Secret + resource is used as the app role id. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + secretRef: + description: |- + Reference to a key in a Secret that contains the App Role secret used + to authenticate with Vault. + The `key` field must be specified and denotes which entry within the Secret + resource is used as the app role secret. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + required: + - path + - secretRef + type: object + cert: + description: |- + Cert authenticates with TLS Certificates by passing client certificate, private key and ca certificate + Cert authentication method + properties: + clientCert: + description: |- + ClientCert is a certificate to authenticate using the Cert Vault + authentication method + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + secretRef: + description: |- + SecretRef to a key in a Secret resource containing client private key to + authenticate with Vault using the Cert authentication method + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + iam: + description: |- + Iam authenticates with vault by passing a special AWS request signed with AWS IAM credentials + AWS IAM authentication method + properties: + externalID: + description: AWS External ID set on assumed IAM roles + type: string + jwt: + description: Specify a service account with IRSA enabled + properties: + serviceAccountRef: + description: A reference to a ServiceAccount resource. + properties: + audiences: + description: |- + Audience specifies the `aud` claim for the service account token + If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity + then this audiences will be appended to the list + items: + type: string + type: array + name: + description: The name of the ServiceAccount resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + required: + - name + type: object + type: object + path: + description: 'Path where the AWS auth method is enabled in Vault, e.g: "aws"' + type: string + region: + description: AWS region + type: string + role: + description: This is the AWS role to be assumed before talking to vault + type: string + secretRef: + description: Specify credentials in a Secret object + properties: + accessKeyIDSecretRef: + description: The AccessKeyID is used for authentication + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + secretAccessKeySecretRef: + description: The SecretAccessKey is used for authentication + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + sessionTokenSecretRef: + description: |- + The SessionToken used for authentication + This must be defined if AccessKeyID and SecretAccessKey are temporary credentials + see: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + vaultAwsIamServerID: + description: 'X-Vault-AWS-IAM-Server-ID is an additional header used by Vault IAM auth method to mitigate against different types of replay attacks. More details here: https://developer.hashicorp.com/vault/docs/auth/aws' + type: string + vaultRole: + description: Vault Role. In vault, a role describes an identity with a set of permissions, groups, or policies you want to attach a user of the secrets engine + type: string + required: + - vaultRole + type: object + jwt: + description: |- + Jwt authenticates with Vault by passing role and JWT token using the + JWT/OIDC authentication method + properties: + kubernetesServiceAccountToken: + description: |- + Optional ServiceAccountToken specifies the Kubernetes service account for which to request + a token for with the `TokenRequest` API. + properties: + audiences: + description: |- + Optional audiences field that will be used to request a temporary Kubernetes service + account token for the service account referenced by `serviceAccountRef`. + Defaults to a single audience `vault` it not specified. + Deprecated: use serviceAccountRef.Audiences instead + items: + type: string + type: array + expirationSeconds: + description: |- + Optional expiration time in seconds that will be used to request a temporary + Kubernetes service account token for the service account referenced by + `serviceAccountRef`. + Deprecated: this will be removed in the future. + Defaults to 10 minutes. + format: int64 + type: integer + serviceAccountRef: + description: Service account field containing the name of a kubernetes ServiceAccount. + properties: + audiences: + description: |- + Audience specifies the `aud` claim for the service account token + If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity + then this audiences will be appended to the list + items: + type: string + type: array + name: + description: The name of the ServiceAccount resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + required: + - name + type: object + required: + - serviceAccountRef + type: object + path: + default: jwt + description: |- + Path where the JWT authentication backend is mounted + in Vault, e.g: "jwt" + type: string + role: + description: |- + Role is a JWT role to authenticate using the JWT/OIDC Vault + authentication method + type: string + secretRef: + description: |- + Optional SecretRef that refers to a key in a Secret resource containing JWT token to + authenticate with Vault using the JWT/OIDC authentication method. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + required: + - path + type: object + kubernetes: + description: |- + Kubernetes authenticates with Vault by passing the ServiceAccount + token stored in the named Secret resource to the Vault server. + properties: + mountPath: + default: kubernetes + description: |- + Path where the Kubernetes authentication backend is mounted in Vault, e.g: + "kubernetes" + type: string + role: + description: |- + A required field containing the Vault Role to assume. A Role binds a + Kubernetes ServiceAccount with a set of Vault policies. + type: string + secretRef: + description: |- + Optional secret field containing a Kubernetes ServiceAccount JWT used + for authenticating with Vault. If a name is specified without a key, + `token` is the default. If one is not specified, the one bound to + the controller will be used. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + serviceAccountRef: + description: |- + Optional service account field containing the name of a kubernetes ServiceAccount. + If the service account is specified, the service account secret token JWT will be used + for authenticating with Vault. If the service account selector is not supplied, + the secretRef will be used instead. + properties: + audiences: + description: |- + Audience specifies the `aud` claim for the service account token + If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity + then this audiences will be appended to the list + items: + type: string + type: array + name: + description: The name of the ServiceAccount resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + required: + - name + type: object + required: + - mountPath + - role + type: object + ldap: + description: |- + Ldap authenticates with Vault by passing username/password pair using + the LDAP authentication method + properties: + path: + default: ldap + description: |- + Path where the LDAP authentication backend is mounted + in Vault, e.g: "ldap" + type: string + secretRef: + description: |- + SecretRef to a key in a Secret resource containing password for the LDAP + user used to authenticate with Vault using the LDAP authentication + method + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + username: + description: |- + Username is a LDAP user name used to authenticate using the LDAP Vault + authentication method + type: string + required: + - path + - username + type: object + namespace: + description: |- + Name of the vault namespace to authenticate to. This can be different than the namespace your secret is in. + Namespaces is a set of features within Vault Enterprise that allows + Vault environments to support Secure Multi-tenancy. e.g: "ns1". + More about namespaces can be found here https://www.vaultproject.io/docs/enterprise/namespaces + This will default to Vault.Namespace field if set, or empty otherwise + type: string + tokenSecretRef: + description: TokenSecretRef authenticates with Vault by presenting a token. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + userPass: + description: UserPass authenticates with Vault by passing username/password pair + properties: + path: + default: user + description: |- + Path where the UserPassword authentication backend is mounted + in Vault, e.g: "user" + type: string + secretRef: + description: |- + SecretRef to a key in a Secret resource containing password for the + user used to authenticate with Vault using the UserPass authentication + method + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + username: + description: |- + Username is a user name used to authenticate using the UserPass Vault + authentication method + type: string + required: + - path + - username + type: object + type: object + caBundle: + description: |- + PEM encoded CA bundle used to validate Vault server certificate. Only used + if the Server URL is using HTTPS protocol. This parameter is ignored for + plain HTTP protocol connection. If not set the system root certificates + are used to validate the TLS connection. + format: byte + type: string + caProvider: + description: The provider for the CA bundle to use to validate Vault server certificate. + properties: + key: + description: The key where the CA certificate can be found in the Secret or ConfigMap. + type: string + name: + description: The name of the object located at the provider type. + type: string + namespace: + description: |- + The namespace the Provider type is in. + Can only be defined when used in a ClusterSecretStore. + type: string + type: + description: The type of provider to use such as "Secret", or "ConfigMap". + enum: + - Secret + - ConfigMap + type: string + required: + - name + - type + type: object + forwardInconsistent: + description: |- + ForwardInconsistent tells Vault to forward read-after-write requests to the Vault + leader instead of simply retrying within a loop. This can increase performance if + the option is enabled serverside. + https://www.vaultproject.io/docs/configuration/replication#allow_forwarding_via_header + type: boolean + headers: + additionalProperties: + type: string + description: Headers to be added in Vault request + type: object + namespace: + description: |- + Name of the vault namespace. Namespaces is a set of features within Vault Enterprise that allows + Vault environments to support Secure Multi-tenancy. e.g: "ns1". + More about namespaces can be found here https://www.vaultproject.io/docs/enterprise/namespaces + type: string + path: + description: |- + Path is the mount path of the Vault KV backend endpoint, e.g: + "secret". The v2 KV secret engine version specific "/data" path suffix + for fetching secrets from Vault is optional and will be appended + if not present in specified path. + type: string + readYourWrites: + description: |- + ReadYourWrites ensures isolated read-after-write semantics by + providing discovered cluster replication states in each request. + More information about eventual consistency in Vault can be found here + https://www.vaultproject.io/docs/enterprise/consistency + type: boolean + server: + description: 'Server is the connection address for the Vault server, e.g: "https://vault.example.com:8200".' + type: string + tls: + description: |- + The configuration used for client side related TLS communication, when the Vault server + requires mutual authentication. Only used if the Server URL is using HTTPS protocol. + This parameter is ignored for plain HTTP protocol connection. + It's worth noting this configuration is different from the "TLS certificates auth method", + which is available under the `auth.cert` section. + properties: + certSecretRef: + description: |- + CertSecretRef is a certificate added to the transport layer + when communicating with the Vault server. + If no key for the Secret is specified, external-secret will default to 'tls.crt'. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + keySecretRef: + description: |- + KeySecretRef to a key in a Secret resource containing client private key + added to the transport layer when communicating with the Vault server. + If no key for the Secret is specified, external-secret will default to 'tls.key'. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + version: + default: v2 + description: |- + Version is the Vault KV secret engine version. This can be either "v1" or + "v2". Version defaults to "v2". + enum: + - v1 + - v2 + type: string + required: + - auth + - server + type: object + webhook: + description: Webhook configures this store to sync secrets using a generic templated webhook + properties: + body: + description: Body + type: string + caBundle: + description: |- + PEM encoded CA bundle used to validate webhook server certificate. Only used + if the Server URL is using HTTPS protocol. This parameter is ignored for + plain HTTP protocol connection. If not set the system root certificates + are used to validate the TLS connection. + format: byte + type: string + caProvider: + description: The provider for the CA bundle to use to validate webhook server certificate. + properties: + key: + description: The key the value inside of the provider type to use, only used with "Secret" type + type: string + name: + description: The name of the object located at the provider type. + type: string + namespace: + description: The namespace the Provider type is in. + type: string + type: + description: The type of provider to use such as "Secret", or "ConfigMap". + enum: + - Secret + - ConfigMap + type: string + required: + - name + - type + type: object + headers: + additionalProperties: + type: string + description: Headers + type: object + method: + description: Webhook Method + type: string + result: + description: Result formatting + properties: + jsonPath: + description: Json path of return value + type: string + type: object + secrets: + description: |- + Secrets to fill in templates + These secrets will be passed to the templating function as key value pairs under the given name + items: + properties: + name: + description: Name of this secret in templates + type: string + secretRef: + description: Secret ref to fill in credentials + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + required: + - name + - secretRef + type: object + type: array + timeout: + description: Timeout + type: string + url: + description: Webhook url to call + type: string + required: + - result + - url + type: object + yandexcertificatemanager: + description: YandexCertificateManager configures this store to sync secrets using Yandex Certificate Manager provider + properties: + apiEndpoint: + description: Yandex.Cloud API endpoint (e.g. 'api.cloud.yandex.net:443') + type: string + auth: + description: Auth defines the information necessary to authenticate against Yandex Certificate Manager + properties: + authorizedKeySecretRef: + description: The authorized key used for authentication + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + caProvider: + description: The provider for the CA bundle to use to validate Yandex.Cloud server certificate. + properties: + certSecretRef: + description: |- + A reference to a specific 'key' within a Secret resource, + In some instances, `key` is a required field. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + required: + - auth + type: object + yandexlockbox: + description: YandexLockbox configures this store to sync secrets using Yandex Lockbox provider + properties: + apiEndpoint: + description: Yandex.Cloud API endpoint (e.g. 'api.cloud.yandex.net:443') + type: string + auth: + description: Auth defines the information necessary to authenticate against Yandex Lockbox + properties: + authorizedKeySecretRef: + description: The authorized key used for authentication + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + caProvider: + description: The provider for the CA bundle to use to validate Yandex.Cloud server certificate. + properties: + certSecretRef: + description: |- + A reference to a specific 'key' within a Secret resource, + In some instances, `key` is a required field. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + required: + - auth + type: object + type: object + refreshInterval: + description: Used to configure store refresh interval in seconds. Empty or 0 will default to the controller config. + type: integer + retrySettings: + description: Used to configure http retries if failed + properties: + maxRetries: + format: int32 + type: integer + retryInterval: + type: string + type: object + required: + - provider + type: object + status: + description: SecretStoreStatus defines the observed state of the SecretStore. + properties: + capabilities: + description: SecretStoreCapabilities defines the possible operations a SecretStore can do. + type: string + conditions: + items: + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + required: + - status + - type + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- if .Values.crds.conversion.enabled }} + conversion: + strategy: Webhook + webhook: + conversionReviewVersions: + - v1 + clientConfig: + service: + name: {{ include "external-secrets.fullname" . }}-webhook + namespace: {{ .Release.Namespace | quote }} + path: /convert +{{- end }} +{{- end }} diff --git a/kubernetes-vault/external-secrets/templates/crds/ecrauthorizationtoken.yaml b/kubernetes-vault/external-secrets/templates/crds/ecrauthorizationtoken.yaml new file mode 100644 index 0000000..f785add --- /dev/null +++ b/kubernetes-vault/external-secrets/templates/crds/ecrauthorizationtoken.yaml @@ -0,0 +1,177 @@ +{{- if .Values.installCRDs }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + {{- with .Values.crds.annotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- if and .Values.crds.conversion.enabled .Values.webhook.certManager.enabled .Values.webhook.certManager.addInjectorAnnotations }} + cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/{{ include "external-secrets.fullname" . }}-webhook + {{- end }} + controller-gen.kubebuilder.io/version: v0.16.2 + labels: + external-secrets.io/component: controller + name: ecrauthorizationtokens.generators.external-secrets.io +spec: + group: generators.external-secrets.io + names: + categories: + - ecrauthorizationtoken + kind: ECRAuthorizationToken + listKind: ECRAuthorizationTokenList + plural: ecrauthorizationtokens + shortNames: + - ecrauthorizationtoken + singular: ecrauthorizationtoken + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + ECRAuthorizationTokenSpec uses the GetAuthorizationToken API to retrieve an + authorization token. + The authorization token is valid for 12 hours. + The authorizationToken returned is a base64 encoded string that can be decoded + and used in a docker login command to authenticate to a registry. + For more information, see Registry authentication (https://docs.aws.amazon.com/AmazonECR/latest/userguide/Registries.html#registry_auth) in the Amazon Elastic Container Registry User Guide. + 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: + auth: + description: Auth defines how to authenticate with AWS + properties: + jwt: + description: Authenticate against AWS using service account tokens. + properties: + serviceAccountRef: + description: A reference to a ServiceAccount resource. + properties: + audiences: + description: |- + Audience specifies the `aud` claim for the service account token + If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity + then this audiences will be appended to the list + items: + type: string + type: array + name: + description: The name of the ServiceAccount resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + required: + - name + type: object + type: object + secretRef: + description: |- + AWSAuthSecretRef holds secret references for AWS credentials + both AccessKeyID and SecretAccessKey must be defined in order to properly authenticate. + properties: + accessKeyIDSecretRef: + description: The AccessKeyID is used for authentication + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + secretAccessKeySecretRef: + description: The SecretAccessKey is used for authentication + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + sessionTokenSecretRef: + description: |- + The SessionToken used for authentication + This must be defined if AccessKeyID and SecretAccessKey are temporary credentials + see: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + type: object + region: + description: Region specifies the region to operate in. + type: string + role: + description: |- + You can assume a role before making calls to the + desired AWS service. + type: string + required: + - region + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- if .Values.crds.conversion.enabled }} + conversion: + strategy: Webhook + webhook: + conversionReviewVersions: + - v1 + clientConfig: + service: + name: {{ include "external-secrets.fullname" . }}-webhook + namespace: {{ .Release.Namespace | quote }} + path: /convert +{{- end }} +{{- end }} diff --git a/kubernetes-vault/external-secrets/templates/crds/externalsecret.yaml b/kubernetes-vault/external-secrets/templates/crds/externalsecret.yaml new file mode 100644 index 0000000..0862f3a --- /dev/null +++ b/kubernetes-vault/external-secrets/templates/crds/externalsecret.yaml @@ -0,0 +1,820 @@ +{{- if .Values.installCRDs }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + {{- with .Values.crds.annotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- if and .Values.crds.conversion.enabled .Values.webhook.certManager.enabled .Values.webhook.certManager.addInjectorAnnotations }} + cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/{{ include "external-secrets.fullname" . }}-webhook + {{- end }} + controller-gen.kubebuilder.io/version: v0.16.2 + labels: + external-secrets.io/component: controller + name: externalsecrets.external-secrets.io +spec: + group: external-secrets.io + names: + categories: + - externalsecrets + kind: ExternalSecret + listKind: ExternalSecretList + plural: externalsecrets + shortNames: + - es + singular: externalsecret + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.secretStoreRef.name + name: Store + type: string + - jsonPath: .spec.refreshInterval + name: Refresh Interval + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].reason + name: Status + type: string + deprecated: true + name: v1alpha1 + schema: + openAPIV3Schema: + description: ExternalSecret is the Schema for the external-secrets 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: ExternalSecretSpec defines the desired state of ExternalSecret. + properties: + data: + description: Data defines the connection between the Kubernetes Secret keys and the Provider data + items: + description: ExternalSecretData defines the connection between the Kubernetes Secret key (spec.data.) and the Provider data. + properties: + remoteRef: + description: ExternalSecretDataRemoteRef defines Provider data location. + properties: + conversionStrategy: + default: Default + description: Used to define a conversion Strategy + enum: + - Default + - Unicode + type: string + key: + description: Key is the key used in the Provider, mandatory + type: string + property: + description: Used to select a specific property of the Provider value (if a map), if supported + type: string + version: + description: Used to select a specific version of the Provider value, if supported + type: string + required: + - key + type: object + secretKey: + type: string + required: + - remoteRef + - secretKey + type: object + type: array + dataFrom: + description: |- + DataFrom is used to fetch all properties from a specific Provider data + If multiple entries are specified, the Secret keys are merged in the specified order + items: + description: ExternalSecretDataRemoteRef defines Provider data location. + properties: + conversionStrategy: + default: Default + description: Used to define a conversion Strategy + enum: + - Default + - Unicode + type: string + key: + description: Key is the key used in the Provider, mandatory + type: string + property: + description: Used to select a specific property of the Provider value (if a map), if supported + type: string + version: + description: Used to select a specific version of the Provider value, if supported + type: string + required: + - key + type: object + type: array + refreshInterval: + default: 1h + description: |- + RefreshInterval is the amount of time before the values are read again from the SecretStore provider + Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h" + May be set to zero to fetch and create it once. Defaults to 1h. + type: string + secretStoreRef: + description: SecretStoreRef defines which SecretStore to fetch the ExternalSecret data. + properties: + kind: + description: |- + Kind of the SecretStore resource (SecretStore or ClusterSecretStore) + Defaults to `SecretStore` + type: string + name: + description: Name of the SecretStore resource + type: string + required: + - name + type: object + target: + description: |- + ExternalSecretTarget defines the Kubernetes Secret to be created + There can be only one target per ExternalSecret. + properties: + creationPolicy: + default: Owner + description: |- + CreationPolicy defines rules on how to create the resulting Secret + Defaults to 'Owner' + enum: + - Owner + - Merge + - None + type: string + immutable: + description: Immutable defines if the final secret will be immutable + type: boolean + name: + description: |- + Name defines the name of the Secret resource to be managed + This field is immutable + Defaults to the .metadata.name of the ExternalSecret resource + type: string + template: + description: Template defines a blueprint for the created Secret resource. + properties: + data: + additionalProperties: + type: string + type: object + engineVersion: + default: v1 + description: |- + EngineVersion specifies the template engine version + that should be used to compile/execute the + template specified in .data and .templateFrom[]. + enum: + - v1 + - v2 + type: string + metadata: + description: ExternalSecretTemplateMetadata defines metadata fields for the Secret blueprint. + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + templateFrom: + items: + maxProperties: 1 + minProperties: 1 + properties: + configMap: + properties: + items: + items: + properties: + key: + type: string + required: + - key + type: object + type: array + name: + type: string + required: + - items + - name + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + required: + - key + type: object + type: array + name: + type: string + required: + - items + - name + type: object + type: object + type: array + type: + type: string + type: object + type: object + required: + - secretStoreRef + - target + type: object + status: + properties: + binding: + description: Binding represents a servicebinding.io Provisioned Service reference to the secret + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + conditions: + items: + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + required: + - status + - type + type: object + type: array + refreshTime: + description: |- + refreshTime is the time and date the external secret was fetched and + the target secret updated + format: date-time + nullable: true + type: string + syncedResourceVersion: + description: SyncedResourceVersion keeps track of the last synced version + type: string + type: object + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .spec.secretStoreRef.name + name: Store + type: string + - jsonPath: .spec.refreshInterval + name: Refresh Interval + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].reason + name: Status + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: ExternalSecret is the Schema for the external-secrets 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: ExternalSecretSpec defines the desired state of ExternalSecret. + properties: + data: + description: Data defines the connection between the Kubernetes Secret keys and the Provider data + items: + description: ExternalSecretData defines the connection between the Kubernetes Secret key (spec.data.) and the Provider data. + properties: + remoteRef: + description: |- + RemoteRef points to the remote secret and defines + which secret (version/property/..) to fetch. + properties: + conversionStrategy: + default: Default + description: Used to define a conversion Strategy + enum: + - Default + - Unicode + type: string + decodingStrategy: + default: None + description: Used to define a decoding Strategy + enum: + - Auto + - Base64 + - Base64URL + - None + type: string + key: + description: Key is the key used in the Provider, mandatory + type: string + metadataPolicy: + default: None + description: Policy for fetching tags/labels from provider secrets, possible options are Fetch, None. Defaults to None + enum: + - None + - Fetch + type: string + property: + description: Used to select a specific property of the Provider value (if a map), if supported + type: string + version: + description: Used to select a specific version of the Provider value, if supported + type: string + required: + - key + type: object + secretKey: + description: |- + SecretKey defines the key in which the controller stores + the value. This is the key in the Kind=Secret + type: string + sourceRef: + description: |- + SourceRef allows you to override the source + from which the value will pulled from. + maxProperties: 1 + properties: + generatorRef: + description: |- + GeneratorRef points to a generator custom resource. + + Deprecated: The generatorRef is not implemented in .data[]. + this will be removed with v1. + properties: + apiVersion: + default: generators.external-secrets.io/v1alpha1 + description: Specify the apiVersion of the generator resource + type: string + kind: + description: Specify the Kind of the resource, e.g. Password, ACRAccessToken etc. + type: string + name: + description: Specify the name of the generator resource + type: string + required: + - kind + - name + type: object + storeRef: + description: SecretStoreRef defines which SecretStore to fetch the ExternalSecret data. + properties: + kind: + description: |- + Kind of the SecretStore resource (SecretStore or ClusterSecretStore) + Defaults to `SecretStore` + type: string + name: + description: Name of the SecretStore resource + type: string + required: + - name + type: object + type: object + required: + - remoteRef + - secretKey + type: object + type: array + dataFrom: + description: |- + DataFrom is used to fetch all properties from a specific Provider data + If multiple entries are specified, the Secret keys are merged in the specified order + items: + properties: + extract: + description: |- + Used to extract multiple key/value pairs from one secret + Note: Extract does not support sourceRef.Generator or sourceRef.GeneratorRef. + properties: + conversionStrategy: + default: Default + description: Used to define a conversion Strategy + enum: + - Default + - Unicode + type: string + decodingStrategy: + default: None + description: Used to define a decoding Strategy + enum: + - Auto + - Base64 + - Base64URL + - None + type: string + key: + description: Key is the key used in the Provider, mandatory + type: string + metadataPolicy: + default: None + description: Policy for fetching tags/labels from provider secrets, possible options are Fetch, None. Defaults to None + enum: + - None + - Fetch + type: string + property: + description: Used to select a specific property of the Provider value (if a map), if supported + type: string + version: + description: Used to select a specific version of the Provider value, if supported + type: string + required: + - key + type: object + find: + description: |- + Used to find secrets based on tags or regular expressions + Note: Find does not support sourceRef.Generator or sourceRef.GeneratorRef. + properties: + conversionStrategy: + default: Default + description: Used to define a conversion Strategy + enum: + - Default + - Unicode + type: string + decodingStrategy: + default: None + description: Used to define a decoding Strategy + enum: + - Auto + - Base64 + - Base64URL + - None + type: string + name: + description: Finds secrets based on the name. + properties: + regexp: + description: Finds secrets base + type: string + type: object + path: + description: A root path to start the find operations. + type: string + tags: + additionalProperties: + type: string + description: Find secrets based on tags. + type: object + type: object + rewrite: + description: |- + Used to rewrite secret Keys after getting them from the secret Provider + Multiple Rewrite operations can be provided. They are applied in a layered order (first to last) + items: + properties: + regexp: + description: |- + Used to rewrite with regular expressions. + The resulting key will be the output of a regexp.ReplaceAll operation. + properties: + source: + description: Used to define the regular expression of a re.Compiler. + type: string + target: + description: Used to define the target pattern of a ReplaceAll operation. + type: string + required: + - source + - target + type: object + transform: + description: |- + Used to apply string transformation on the secrets. + The resulting key will be the output of the template applied by the operation. + properties: + template: + description: |- + Used to define the template to apply on the secret name. + `.value ` will specify the secret name in the template. + type: string + required: + - template + type: object + type: object + type: array + sourceRef: + description: |- + SourceRef points to a store or generator + which contains secret values ready to use. + Use this in combination with Extract or Find pull values out of + a specific SecretStore. + When sourceRef points to a generator Extract or Find is not supported. + The generator returns a static map of values + maxProperties: 1 + properties: + generatorRef: + description: GeneratorRef points to a generator custom resource. + properties: + apiVersion: + default: generators.external-secrets.io/v1alpha1 + description: Specify the apiVersion of the generator resource + type: string + kind: + description: Specify the Kind of the resource, e.g. Password, ACRAccessToken etc. + type: string + name: + description: Specify the name of the generator resource + type: string + required: + - kind + - name + type: object + storeRef: + description: SecretStoreRef defines which SecretStore to fetch the ExternalSecret data. + properties: + kind: + description: |- + Kind of the SecretStore resource (SecretStore or ClusterSecretStore) + Defaults to `SecretStore` + type: string + name: + description: Name of the SecretStore resource + type: string + required: + - name + type: object + type: object + type: object + type: array + refreshInterval: + default: 1h + description: |- + RefreshInterval is the amount of time before the values are read again from the SecretStore provider + Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h" + May be set to zero to fetch and create it once. Defaults to 1h. + type: string + secretStoreRef: + description: SecretStoreRef defines which SecretStore to fetch the ExternalSecret data. + properties: + kind: + description: |- + Kind of the SecretStore resource (SecretStore or ClusterSecretStore) + Defaults to `SecretStore` + type: string + name: + description: Name of the SecretStore resource + type: string + required: + - name + type: object + target: + default: + creationPolicy: Owner + deletionPolicy: Retain + description: |- + ExternalSecretTarget defines the Kubernetes Secret to be created + There can be only one target per ExternalSecret. + properties: + creationPolicy: + default: Owner + description: |- + CreationPolicy defines rules on how to create the resulting Secret + Defaults to 'Owner' + enum: + - Owner + - Orphan + - Merge + - None + type: string + deletionPolicy: + default: Retain + description: |- + DeletionPolicy defines rules on how to delete the resulting Secret + Defaults to 'Retain' + enum: + - Delete + - Merge + - Retain + type: string + immutable: + description: Immutable defines if the final secret will be immutable + type: boolean + name: + description: |- + Name defines the name of the Secret resource to be managed + This field is immutable + Defaults to the .metadata.name of the ExternalSecret resource + type: string + template: + description: Template defines a blueprint for the created Secret resource. + properties: + data: + additionalProperties: + type: string + type: object + engineVersion: + default: v2 + description: |- + EngineVersion specifies the template engine version + that should be used to compile/execute the + template specified in .data and .templateFrom[]. + enum: + - v1 + - v2 + type: string + mergePolicy: + default: Replace + enum: + - Replace + - Merge + type: string + metadata: + description: ExternalSecretTemplateMetadata defines metadata fields for the Secret blueprint. + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + templateFrom: + items: + properties: + configMap: + properties: + items: + items: + properties: + key: + type: string + templateAs: + default: Values + enum: + - Values + - KeysAndValues + type: string + required: + - key + type: object + type: array + name: + type: string + required: + - items + - name + type: object + literal: + type: string + secret: + properties: + items: + items: + properties: + key: + type: string + templateAs: + default: Values + enum: + - Values + - KeysAndValues + type: string + required: + - key + type: object + type: array + name: + type: string + required: + - items + - name + type: object + target: + default: Data + enum: + - Data + - Annotations + - Labels + type: string + type: object + type: array + type: + type: string + type: object + type: object + type: object + status: + properties: + binding: + description: Binding represents a servicebinding.io Provisioned Service reference to the secret + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + conditions: + items: + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + required: + - status + - type + type: object + type: array + refreshTime: + description: |- + refreshTime is the time and date the external secret was fetched and + the target secret updated + format: date-time + nullable: true + type: string + syncedResourceVersion: + description: SyncedResourceVersion keeps track of the last synced version + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- if .Values.crds.conversion.enabled }} + conversion: + strategy: Webhook + webhook: + conversionReviewVersions: + - v1 + clientConfig: + service: + name: {{ include "external-secrets.fullname" . }}-webhook + namespace: {{ .Release.Namespace | quote }} + path: /convert +{{- end }} +{{- end }} diff --git a/kubernetes-vault/external-secrets/templates/crds/fake.yaml b/kubernetes-vault/external-secrets/templates/crds/fake.yaml new file mode 100644 index 0000000..38cacf6 --- /dev/null +++ b/kubernetes-vault/external-secrets/templates/crds/fake.yaml @@ -0,0 +1,86 @@ +{{- if .Values.installCRDs }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + {{- with .Values.crds.annotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- if and .Values.crds.conversion.enabled .Values.webhook.certManager.enabled .Values.webhook.certManager.addInjectorAnnotations }} + cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/{{ include "external-secrets.fullname" . }}-webhook + {{- end }} + controller-gen.kubebuilder.io/version: v0.16.2 + labels: + external-secrets.io/component: controller + name: fakes.generators.external-secrets.io +spec: + group: generators.external-secrets.io + names: + categories: + - fake + kind: Fake + listKind: FakeList + plural: fakes + shortNames: + - fake + singular: fake + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + Fake generator is used for testing. It lets you define + a static set of credentials that is always returned. + 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: FakeSpec contains the static data. + properties: + controller: + description: |- + Used to select the correct ESO controller (think: ingress.ingressClassName) + The ESO controller is instantiated with a specific controller name and filters VDS based on this property + type: string + data: + additionalProperties: + type: string + description: |- + Data defines the static data returned + by this generator. + type: object + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- if .Values.crds.conversion.enabled }} + conversion: + strategy: Webhook + webhook: + conversionReviewVersions: + - v1 + clientConfig: + service: + name: {{ include "external-secrets.fullname" . }}-webhook + namespace: {{ .Release.Namespace | quote }} + path: /convert +{{- end }} +{{- end }} diff --git a/kubernetes-vault/external-secrets/templates/crds/gcraccesstoken.yaml b/kubernetes-vault/external-secrets/templates/crds/gcraccesstoken.yaml new file mode 100644 index 0000000..b71777a --- /dev/null +++ b/kubernetes-vault/external-secrets/templates/crds/gcraccesstoken.yaml @@ -0,0 +1,138 @@ +{{- if .Values.installCRDs }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + {{- with .Values.crds.annotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- if and .Values.crds.conversion.enabled .Values.webhook.certManager.enabled .Values.webhook.certManager.addInjectorAnnotations }} + cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/{{ include "external-secrets.fullname" . }}-webhook + {{- end }} + controller-gen.kubebuilder.io/version: v0.16.2 + labels: + external-secrets.io/component: controller + name: gcraccesstokens.generators.external-secrets.io +spec: + group: generators.external-secrets.io + names: + categories: + - gcraccesstoken + kind: GCRAccessToken + listKind: GCRAccessTokenList + plural: gcraccesstokens + shortNames: + - gcraccesstoken + singular: gcraccesstoken + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + GCRAccessToken generates an GCP access token + that can be used to authenticate with GCR. + 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: + auth: + description: Auth defines the means for authenticating with GCP + properties: + secretRef: + properties: + secretAccessKeySecretRef: + description: The SecretAccessKey is used for authentication + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + workloadIdentity: + properties: + clusterLocation: + type: string + clusterName: + type: string + clusterProjectID: + type: string + serviceAccountRef: + description: A reference to a ServiceAccount resource. + properties: + audiences: + description: |- + Audience specifies the `aud` claim for the service account token + If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity + then this audiences will be appended to the list + items: + type: string + type: array + name: + description: The name of the ServiceAccount resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + required: + - name + type: object + required: + - clusterLocation + - clusterName + - serviceAccountRef + type: object + type: object + projectID: + description: ProjectID defines which project to use to authenticate with + type: string + required: + - auth + - projectID + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- if .Values.crds.conversion.enabled }} + conversion: + strategy: Webhook + webhook: + conversionReviewVersions: + - v1 + clientConfig: + service: + name: {{ include "external-secrets.fullname" . }}-webhook + namespace: {{ .Release.Namespace | quote }} + path: /convert +{{- end }} +{{- end }} diff --git a/kubernetes-vault/external-secrets/templates/crds/githubaccesstoken.yaml b/kubernetes-vault/external-secrets/templates/crds/githubaccesstoken.yaml new file mode 100644 index 0000000..e1bc7e1 --- /dev/null +++ b/kubernetes-vault/external-secrets/templates/crds/githubaccesstoken.yaml @@ -0,0 +1,112 @@ +{{- if .Values.installCRDs }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + {{- with .Values.crds.annotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- if and .Values.crds.conversion.enabled .Values.webhook.certManager.enabled .Values.webhook.certManager.addInjectorAnnotations }} + cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/{{ include "external-secrets.fullname" . }}-webhook + {{- end }} + controller-gen.kubebuilder.io/version: v0.16.2 + labels: + external-secrets.io/component: controller + name: githubaccesstokens.generators.external-secrets.io +spec: + group: generators.external-secrets.io + names: + categories: + - githubaccesstoken + kind: GithubAccessToken + listKind: GithubAccessTokenList + plural: githubaccesstokens + shortNames: + - githubaccesstoken + singular: githubaccesstoken + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: GithubAccessToken generates ghs_ accessToken + 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: + appID: + type: string + auth: + description: Auth configures how ESO authenticates with a Github instance. + properties: + privateKey: + properties: + secretRef: + description: |- + A reference to a specific 'key' within a Secret resource, + In some instances, `key` is a required field. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + required: + - secretRef + type: object + required: + - privateKey + type: object + installID: + type: string + url: + description: URL configures the Github instance URL. Defaults to https://github.com/. + type: string + required: + - appID + - auth + - installID + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- if .Values.crds.conversion.enabled }} + conversion: + strategy: Webhook + webhook: + conversionReviewVersions: + - v1 + clientConfig: + service: + name: {{ include "external-secrets.fullname" . }}-webhook + namespace: {{ .Release.Namespace | quote }} + path: /convert +{{- end }} +{{- end }} diff --git a/kubernetes-vault/external-secrets/templates/crds/password.yaml b/kubernetes-vault/external-secrets/templates/crds/password.yaml new file mode 100644 index 0000000..034ceb3 --- /dev/null +++ b/kubernetes-vault/external-secrets/templates/crds/password.yaml @@ -0,0 +1,108 @@ +{{- if .Values.installCRDs }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + {{- with .Values.crds.annotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- if and .Values.crds.conversion.enabled .Values.webhook.certManager.enabled .Values.webhook.certManager.addInjectorAnnotations }} + cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/{{ include "external-secrets.fullname" . }}-webhook + {{- end }} + controller-gen.kubebuilder.io/version: v0.16.2 + labels: + external-secrets.io/component: controller + name: passwords.generators.external-secrets.io +spec: + group: generators.external-secrets.io + names: + categories: + - password + kind: Password + listKind: PasswordList + plural: passwords + shortNames: + - password + singular: password + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + Password generates a random password based on the + configuration parameters in spec. + You can specify the length, characterset and other attributes. + 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: PasswordSpec controls the behavior of the password generator. + properties: + allowRepeat: + default: false + description: set AllowRepeat to true to allow repeating characters. + type: boolean + digits: + description: |- + Digits specifies the number of digits in the generated + password. If omitted it defaults to 25% of the length of the password + type: integer + length: + default: 24 + description: |- + Length of the password to be generated. + Defaults to 24 + type: integer + noUpper: + default: false + description: Set NoUpper to disable uppercase characters + type: boolean + symbolCharacters: + description: |- + SymbolCharacters specifies the special characters that should be used + in the generated password. + type: string + symbols: + description: |- + Symbols specifies the number of symbol characters in the generated + password. If omitted it defaults to 25% of the length of the password + type: integer + required: + - allowRepeat + - length + - noUpper + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- if .Values.crds.conversion.enabled }} + conversion: + strategy: Webhook + webhook: + conversionReviewVersions: + - v1 + clientConfig: + service: + name: {{ include "external-secrets.fullname" . }}-webhook + namespace: {{ .Release.Namespace | quote }} + path: /convert +{{- end }} +{{- end }} diff --git a/kubernetes-vault/external-secrets/templates/crds/pushsecret.yaml b/kubernetes-vault/external-secrets/templates/crds/pushsecret.yaml new file mode 100644 index 0000000..f9c12b7 --- /dev/null +++ b/kubernetes-vault/external-secrets/templates/crds/pushsecret.yaml @@ -0,0 +1,386 @@ +{{- if and (.Values.installCRDs) (.Values.crds.createPushSecret) }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + {{- with .Values.crds.annotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- if and .Values.crds.conversion.enabled .Values.webhook.certManager.enabled .Values.webhook.certManager.addInjectorAnnotations }} + cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/{{ include "external-secrets.fullname" . }}-webhook + {{- end }} + controller-gen.kubebuilder.io/version: v0.16.2 + name: pushsecrets.external-secrets.io +spec: + group: external-secrets.io + names: + categories: + - pushsecrets + kind: PushSecret + listKind: PushSecretList + plural: pushsecrets + singular: pushsecret + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: AGE + type: date + - jsonPath: .status.conditions[?(@.type=="Ready")].reason + name: Status + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: PushSecretSpec configures the behavior of the PushSecret. + properties: + data: + description: Secret Data that should be pushed to providers + items: + properties: + conversionStrategy: + default: None + description: Used to define a conversion Strategy for the secret keys + enum: + - None + - ReverseUnicode + type: string + match: + description: Match a given Secret Key to be pushed to the provider. + properties: + remoteRef: + description: Remote Refs to push to providers. + properties: + property: + description: Name of the property in the resulting secret + type: string + remoteKey: + description: Name of the resulting provider secret. + type: string + required: + - remoteKey + type: object + secretKey: + description: Secret Key to be pushed + type: string + required: + - remoteRef + type: object + metadata: + description: |- + Metadata is metadata attached to the secret. + The structure of metadata is provider specific, please look it up in the provider documentation. + x-kubernetes-preserve-unknown-fields: true + required: + - match + type: object + type: array + deletionPolicy: + default: None + description: 'Deletion Policy to handle Secrets in the provider. Possible Values: "Delete/None". Defaults to "None".' + enum: + - Delete + - None + type: string + refreshInterval: + description: The Interval to which External Secrets will try to push a secret definition + type: string + secretStoreRefs: + items: + properties: + kind: + default: SecretStore + description: |- + Kind of the SecretStore resource (SecretStore or ClusterSecretStore) + Defaults to `SecretStore` + type: string + labelSelector: + description: Optionally, sync to secret stores with label selector + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + name: + description: Optionally, sync to the SecretStore of the given name + type: string + type: object + type: array + selector: + description: The Secret Selector (k8s source) for the Push Secret + properties: + secret: + description: Select a Secret to Push. + properties: + name: + description: Name of the Secret. The Secret must exist in the same namespace as the PushSecret manifest. + type: string + required: + - name + type: object + required: + - secret + type: object + template: + description: Template defines a blueprint for the created Secret resource. + properties: + data: + additionalProperties: + type: string + type: object + engineVersion: + default: v2 + description: |- + EngineVersion specifies the template engine version + that should be used to compile/execute the + template specified in .data and .templateFrom[]. + enum: + - v1 + - v2 + type: string + mergePolicy: + default: Replace + enum: + - Replace + - Merge + type: string + metadata: + description: ExternalSecretTemplateMetadata defines metadata fields for the Secret blueprint. + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + templateFrom: + items: + properties: + configMap: + properties: + items: + items: + properties: + key: + type: string + templateAs: + default: Values + enum: + - Values + - KeysAndValues + type: string + required: + - key + type: object + type: array + name: + type: string + required: + - items + - name + type: object + literal: + type: string + secret: + properties: + items: + items: + properties: + key: + type: string + templateAs: + default: Values + enum: + - Values + - KeysAndValues + type: string + required: + - key + type: object + type: array + name: + type: string + required: + - items + - name + type: object + target: + default: Data + enum: + - Data + - Annotations + - Labels + type: string + type: object + type: array + type: + type: string + type: object + updatePolicy: + default: Replace + description: 'UpdatePolicy to handle Secrets in the provider. Possible Values: "Replace/IfNotExists". Defaults to "Replace".' + enum: + - Replace + - IfNotExists + type: string + required: + - secretStoreRefs + - selector + type: object + status: + description: PushSecretStatus indicates the history of the status of PushSecret. + properties: + conditions: + items: + description: PushSecretStatusCondition indicates the status of the PushSecret. + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + description: PushSecretConditionType indicates the condition of the PushSecret. + type: string + required: + - status + - type + type: object + type: array + refreshTime: + description: |- + refreshTime is the time and date the external secret was fetched and + the target secret updated + format: date-time + nullable: true + type: string + syncedPushSecrets: + additionalProperties: + additionalProperties: + properties: + conversionStrategy: + default: None + description: Used to define a conversion Strategy for the secret keys + enum: + - None + - ReverseUnicode + type: string + match: + description: Match a given Secret Key to be pushed to the provider. + properties: + remoteRef: + description: Remote Refs to push to providers. + properties: + property: + description: Name of the property in the resulting secret + type: string + remoteKey: + description: Name of the resulting provider secret. + type: string + required: + - remoteKey + type: object + secretKey: + description: Secret Key to be pushed + type: string + required: + - remoteRef + type: object + metadata: + description: |- + Metadata is metadata attached to the secret. + The structure of metadata is provider specific, please look it up in the provider documentation. + x-kubernetes-preserve-unknown-fields: true + required: + - match + type: object + type: object + description: |- + Synced PushSecrets, including secrets that already exist in provider. + Matches secret stores to PushSecretData that was stored to that secret store. + type: object + syncedResourceVersion: + description: SyncedResourceVersion keeps track of the last synced version. + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- if .Values.crds.conversion.enabled }} + conversion: + strategy: Webhook + webhook: + conversionReviewVersions: + - v1 + clientConfig: + service: + name: {{ include "external-secrets.fullname" . }}-webhook + namespace: {{ .Release.Namespace | quote }} + path: /convert +{{- end }} +{{- end }} diff --git a/kubernetes-vault/external-secrets/templates/crds/secretstore.yaml b/kubernetes-vault/external-secrets/templates/crds/secretstore.yaml new file mode 100644 index 0000000..dd756df --- /dev/null +++ b/kubernetes-vault/external-secrets/templates/crds/secretstore.yaml @@ -0,0 +1,4601 @@ +{{- if .Values.installCRDs }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + {{- with .Values.crds.annotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- if and .Values.crds.conversion.enabled .Values.webhook.certManager.enabled .Values.webhook.certManager.addInjectorAnnotations }} + cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/{{ include "external-secrets.fullname" . }}-webhook + {{- end }} + controller-gen.kubebuilder.io/version: v0.16.2 + labels: + external-secrets.io/component: controller + name: secretstores.external-secrets.io +spec: + group: external-secrets.io + names: + categories: + - externalsecrets + kind: SecretStore + listKind: SecretStoreList + plural: secretstores + shortNames: + - ss + singular: secretstore + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: AGE + type: date + - jsonPath: .status.conditions[?(@.type=="Ready")].reason + name: Status + type: string + deprecated: true + name: v1alpha1 + schema: + openAPIV3Schema: + description: SecretStore represents a secure external location for storing secrets, which can be referenced as part of `storeRef` fields. + 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: SecretStoreSpec defines the desired state of SecretStore. + properties: + controller: + description: |- + Used to select the correct ESO controller (think: ingress.ingressClassName) + The ESO controller is instantiated with a specific controller name and filters ES based on this property + type: string + provider: + description: Used to configure the provider. Only one provider may be set + maxProperties: 1 + minProperties: 1 + properties: + akeyless: + description: Akeyless configures this store to sync secrets using Akeyless Vault provider + properties: + akeylessGWApiURL: + description: Akeyless GW API Url from which the secrets to be fetched from. + type: string + authSecretRef: + description: Auth configures how the operator authenticates with Akeyless. + properties: + kubernetesAuth: + description: |- + Kubernetes authenticates with Akeyless by passing the ServiceAccount + token stored in the named Secret resource. + properties: + accessID: + description: the Akeyless Kubernetes auth-method access-id + type: string + k8sConfName: + description: Kubernetes-auth configuration name in Akeyless-Gateway + type: string + secretRef: + description: |- + Optional secret field containing a Kubernetes ServiceAccount JWT used + for authenticating with Akeyless. If a name is specified without a key, + `token` is the default. If one is not specified, the one bound to + the controller will be used. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + serviceAccountRef: + description: |- + Optional service account field containing the name of a kubernetes ServiceAccount. + If the service account is specified, the service account secret token JWT will be used + for authenticating with Akeyless. If the service account selector is not supplied, + the secretRef will be used instead. + properties: + audiences: + description: |- + Audience specifies the `aud` claim for the service account token + If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity + then this audiences will be appended to the list + items: + type: string + type: array + name: + description: The name of the ServiceAccount resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + required: + - name + type: object + required: + - accessID + - k8sConfName + type: object + secretRef: + description: |- + Reference to a Secret that contains the details + to authenticate with Akeyless. + properties: + accessID: + description: The SecretAccessID is used for authentication + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + accessType: + description: |- + A reference to a specific 'key' within a Secret resource, + In some instances, `key` is a required field. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + accessTypeParam: + description: |- + A reference to a specific 'key' within a Secret resource, + In some instances, `key` is a required field. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + type: object + caBundle: + description: |- + PEM/base64 encoded CA bundle used to validate Akeyless Gateway certificate. Only used + if the AkeylessGWApiURL URL is using HTTPS protocol. If not set the system root certificates + are used to validate the TLS connection. + format: byte + type: string + caProvider: + description: The provider for the CA bundle to use to validate Akeyless Gateway certificate. + properties: + key: + description: The key the value inside of the provider type to use, only used with "Secret" type + type: string + name: + description: The name of the object located at the provider type. + type: string + namespace: + description: The namespace the Provider type is in. + type: string + type: + description: The type of provider to use such as "Secret", or "ConfigMap". + enum: + - Secret + - ConfigMap + type: string + required: + - name + - type + type: object + required: + - akeylessGWApiURL + - authSecretRef + type: object + alibaba: + description: Alibaba configures this store to sync secrets using Alibaba Cloud provider + properties: + auth: + description: AlibabaAuth contains a secretRef for credentials. + properties: + rrsa: + description: Authenticate against Alibaba using RRSA. + properties: + oidcProviderArn: + type: string + oidcTokenFilePath: + type: string + roleArn: + type: string + sessionName: + type: string + required: + - oidcProviderArn + - oidcTokenFilePath + - roleArn + - sessionName + type: object + secretRef: + description: AlibabaAuthSecretRef holds secret references for Alibaba credentials. + properties: + accessKeyIDSecretRef: + description: The AccessKeyID is used for authentication + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + accessKeySecretSecretRef: + description: The AccessKeySecret is used for authentication + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + required: + - accessKeyIDSecretRef + - accessKeySecretSecretRef + type: object + type: object + regionID: + description: Alibaba Region to be used for the provider + type: string + required: + - auth + - regionID + type: object + aws: + description: AWS configures this store to sync secrets using AWS Secret Manager provider + properties: + auth: + description: |- + Auth defines the information necessary to authenticate against AWS + if not set aws sdk will infer credentials from your environment + see: https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials + properties: + jwt: + description: Authenticate against AWS using service account tokens. + properties: + serviceAccountRef: + description: A reference to a ServiceAccount resource. + properties: + audiences: + description: |- + Audience specifies the `aud` claim for the service account token + If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity + then this audiences will be appended to the list + items: + type: string + type: array + name: + description: The name of the ServiceAccount resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + required: + - name + type: object + type: object + secretRef: + description: |- + AWSAuthSecretRef holds secret references for AWS credentials + both AccessKeyID and SecretAccessKey must be defined in order to properly authenticate. + properties: + accessKeyIDSecretRef: + description: The AccessKeyID is used for authentication + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + secretAccessKeySecretRef: + description: The SecretAccessKey is used for authentication + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + type: object + region: + description: AWS Region to be used for the provider + type: string + role: + description: Role is a Role ARN which the SecretManager provider will assume + type: string + service: + description: Service defines which service should be used to fetch the secrets + enum: + - SecretsManager + - ParameterStore + type: string + required: + - region + - service + type: object + azurekv: + description: AzureKV configures this store to sync secrets using Azure Key Vault provider + properties: + authSecretRef: + description: Auth configures how the operator authenticates with Azure. Required for ServicePrincipal auth type. + properties: + clientId: + description: The Azure clientId of the service principle used for authentication. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + clientSecret: + description: The Azure ClientSecret of the service principle used for authentication. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + authType: + default: ServicePrincipal + description: |- + Auth type defines how to authenticate to the keyvault service. + Valid values are: + - "ServicePrincipal" (default): Using a service principal (tenantId, clientId, clientSecret) + - "ManagedIdentity": Using Managed Identity assigned to the pod (see aad-pod-identity) + enum: + - ServicePrincipal + - ManagedIdentity + - WorkloadIdentity + type: string + identityId: + description: If multiple Managed Identity is assigned to the pod, you can select the one to be used + type: string + serviceAccountRef: + description: |- + ServiceAccountRef specified the service account + that should be used when authenticating with WorkloadIdentity. + properties: + audiences: + description: |- + Audience specifies the `aud` claim for the service account token + If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity + then this audiences will be appended to the list + items: + type: string + type: array + name: + description: The name of the ServiceAccount resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + required: + - name + type: object + tenantId: + description: TenantID configures the Azure Tenant to send requests to. Required for ServicePrincipal auth type. + type: string + vaultUrl: + description: Vault Url from which the secrets to be fetched from. + type: string + required: + - vaultUrl + type: object + fake: + description: Fake configures a store with static key/value pairs + properties: + data: + items: + properties: + key: + type: string + value: + type: string + valueMap: + additionalProperties: + type: string + type: object + version: + type: string + required: + - key + type: object + type: array + required: + - data + type: object + gcpsm: + description: GCPSM configures this store to sync secrets using Google Cloud Platform Secret Manager provider + properties: + auth: + description: Auth defines the information necessary to authenticate against GCP + properties: + secretRef: + properties: + secretAccessKeySecretRef: + description: The SecretAccessKey is used for authentication + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + workloadIdentity: + properties: + clusterLocation: + type: string + clusterName: + type: string + clusterProjectID: + type: string + serviceAccountRef: + description: A reference to a ServiceAccount resource. + properties: + audiences: + description: |- + Audience specifies the `aud` claim for the service account token + If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity + then this audiences will be appended to the list + items: + type: string + type: array + name: + description: The name of the ServiceAccount resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + required: + - name + type: object + required: + - clusterLocation + - clusterName + - serviceAccountRef + type: object + type: object + projectID: + description: ProjectID project where secret is located + type: string + type: object + gitlab: + description: GitLab configures this store to sync secrets using GitLab Variables provider + properties: + auth: + description: Auth configures how secret-manager authenticates with a GitLab instance. + properties: + SecretRef: + properties: + accessToken: + description: AccessToken is used for authentication. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + required: + - SecretRef + type: object + projectID: + description: ProjectID specifies a project where secrets are located. + type: string + url: + description: URL configures the GitLab instance URL. Defaults to https://gitlab.com/. + type: string + required: + - auth + type: object + ibm: + description: IBM configures this store to sync secrets using IBM Cloud provider + properties: + auth: + description: Auth configures how secret-manager authenticates with the IBM secrets manager. + properties: + secretRef: + properties: + secretApiKeySecretRef: + description: The SecretAccessKey is used for authentication + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + required: + - secretRef + type: object + serviceUrl: + description: ServiceURL is the Endpoint URL that is specific to the Secrets Manager service instance + type: string + required: + - auth + type: object + kubernetes: + description: Kubernetes configures this store to sync secrets using a Kubernetes cluster provider + properties: + auth: + description: Auth configures how secret-manager authenticates with a Kubernetes instance. + maxProperties: 1 + minProperties: 1 + properties: + cert: + description: has both clientCert and clientKey as secretKeySelector + properties: + clientCert: + description: |- + A reference to a specific 'key' within a Secret resource, + In some instances, `key` is a required field. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + clientKey: + description: |- + A reference to a specific 'key' within a Secret resource, + In some instances, `key` is a required field. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + serviceAccount: + description: points to a service account that should be used for authentication + properties: + serviceAccount: + description: A reference to a ServiceAccount resource. + properties: + audiences: + description: |- + Audience specifies the `aud` claim for the service account token + If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity + then this audiences will be appended to the list + items: + type: string + type: array + name: + description: The name of the ServiceAccount resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + required: + - name + type: object + type: object + token: + description: use static token to authenticate with + properties: + bearerToken: + description: |- + A reference to a specific 'key' within a Secret resource, + In some instances, `key` is a required field. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + type: object + remoteNamespace: + default: default + description: Remote namespace to fetch the secrets from + type: string + server: + description: configures the Kubernetes server Address. + properties: + caBundle: + description: CABundle is a base64-encoded CA certificate + format: byte + type: string + caProvider: + description: 'see: https://external-secrets.io/v0.4.1/spec/#external-secrets.io/v1alpha1.CAProvider' + properties: + key: + description: The key the value inside of the provider type to use, only used with "Secret" type + type: string + name: + description: The name of the object located at the provider type. + type: string + namespace: + description: The namespace the Provider type is in. + type: string + type: + description: The type of provider to use such as "Secret", or "ConfigMap". + enum: + - Secret + - ConfigMap + type: string + required: + - name + - type + type: object + url: + default: kubernetes.default + description: configures the Kubernetes server Address. + type: string + type: object + required: + - auth + type: object + oracle: + description: Oracle configures this store to sync secrets using Oracle Vault provider + properties: + auth: + description: |- + Auth configures how secret-manager authenticates with the Oracle Vault. + If empty, instance principal is used. Optionally, the authenticating principal type + and/or user data may be supplied for the use of workload identity and user principal. + properties: + secretRef: + description: SecretRef to pass through sensitive information. + properties: + fingerprint: + description: Fingerprint is the fingerprint of the API private key. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + privatekey: + description: PrivateKey is the user's API Signing Key in PEM format, used for authentication. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + required: + - fingerprint + - privatekey + type: object + tenancy: + description: Tenancy is the tenancy OCID where user is located. + type: string + user: + description: User is an access OCID specific to the account. + type: string + required: + - secretRef + - tenancy + - user + type: object + compartment: + description: |- + Compartment is the vault compartment OCID. + Required for PushSecret + type: string + encryptionKey: + description: |- + EncryptionKey is the OCID of the encryption key within the vault. + Required for PushSecret + type: string + principalType: + description: |- + The type of principal to use for authentication. If left blank, the Auth struct will + determine the principal type. This optional field must be specified if using + workload identity. + enum: + - "" + - UserPrincipal + - InstancePrincipal + - Workload + type: string + region: + description: Region is the region where vault is located. + type: string + serviceAccountRef: + description: |- + ServiceAccountRef specified the service account + that should be used when authenticating with WorkloadIdentity. + properties: + audiences: + description: |- + Audience specifies the `aud` claim for the service account token + If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity + then this audiences will be appended to the list + items: + type: string + type: array + name: + description: The name of the ServiceAccount resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + required: + - name + type: object + vault: + description: Vault is the vault's OCID of the specific vault where secret is located. + type: string + required: + - region + - vault + type: object + passworddepot: + description: Configures a store to sync secrets with a Password Depot instance. + properties: + auth: + description: Auth configures how secret-manager authenticates with a Password Depot instance. + properties: + secretRef: + properties: + credentials: + description: Username / Password is used for authentication. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + required: + - secretRef + type: object + database: + description: Database to use as source + type: string + host: + description: URL configures the Password Depot instance URL. + type: string + required: + - auth + - database + - host + type: object + vault: + description: Vault configures this store to sync secrets using Hashi provider + properties: + auth: + description: Auth configures how secret-manager authenticates with the Vault server. + properties: + appRole: + description: |- + AppRole authenticates with Vault using the App Role auth mechanism, + with the role and secret stored in a Kubernetes Secret resource. + properties: + path: + default: approle + description: |- + Path where the App Role authentication backend is mounted + in Vault, e.g: "approle" + type: string + roleId: + description: |- + RoleID configured in the App Role authentication backend when setting + up the authentication backend in Vault. + type: string + secretRef: + description: |- + Reference to a key in a Secret that contains the App Role secret used + to authenticate with Vault. + The `key` field must be specified and denotes which entry within the Secret + resource is used as the app role secret. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + required: + - path + - roleId + - secretRef + type: object + cert: + description: |- + Cert authenticates with TLS Certificates by passing client certificate, private key and ca certificate + Cert authentication method + properties: + clientCert: + description: |- + ClientCert is a certificate to authenticate using the Cert Vault + authentication method + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + secretRef: + description: |- + SecretRef to a key in a Secret resource containing client private key to + authenticate with Vault using the Cert authentication method + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + jwt: + description: |- + Jwt authenticates with Vault by passing role and JWT token using the + JWT/OIDC authentication method + properties: + kubernetesServiceAccountToken: + description: |- + Optional ServiceAccountToken specifies the Kubernetes service account for which to request + a token for with the `TokenRequest` API. + properties: + audiences: + description: |- + Optional audiences field that will be used to request a temporary Kubernetes service + account token for the service account referenced by `serviceAccountRef`. + Defaults to a single audience `vault` it not specified. + items: + type: string + type: array + expirationSeconds: + description: |- + Optional expiration time in seconds that will be used to request a temporary + Kubernetes service account token for the service account referenced by + `serviceAccountRef`. + Defaults to 10 minutes. + format: int64 + type: integer + serviceAccountRef: + description: Service account field containing the name of a kubernetes ServiceAccount. + properties: + audiences: + description: |- + Audience specifies the `aud` claim for the service account token + If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity + then this audiences will be appended to the list + items: + type: string + type: array + name: + description: The name of the ServiceAccount resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + required: + - name + type: object + required: + - serviceAccountRef + type: object + path: + default: jwt + description: |- + Path where the JWT authentication backend is mounted + in Vault, e.g: "jwt" + type: string + role: + description: |- + Role is a JWT role to authenticate using the JWT/OIDC Vault + authentication method + type: string + secretRef: + description: |- + Optional SecretRef that refers to a key in a Secret resource containing JWT token to + authenticate with Vault using the JWT/OIDC authentication method. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + required: + - path + type: object + kubernetes: + description: |- + Kubernetes authenticates with Vault by passing the ServiceAccount + token stored in the named Secret resource to the Vault server. + properties: + mountPath: + default: kubernetes + description: |- + Path where the Kubernetes authentication backend is mounted in Vault, e.g: + "kubernetes" + type: string + role: + description: |- + A required field containing the Vault Role to assume. A Role binds a + Kubernetes ServiceAccount with a set of Vault policies. + type: string + secretRef: + description: |- + Optional secret field containing a Kubernetes ServiceAccount JWT used + for authenticating with Vault. If a name is specified without a key, + `token` is the default. If one is not specified, the one bound to + the controller will be used. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + serviceAccountRef: + description: |- + Optional service account field containing the name of a kubernetes ServiceAccount. + If the service account is specified, the service account secret token JWT will be used + for authenticating with Vault. If the service account selector is not supplied, + the secretRef will be used instead. + properties: + audiences: + description: |- + Audience specifies the `aud` claim for the service account token + If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity + then this audiences will be appended to the list + items: + type: string + type: array + name: + description: The name of the ServiceAccount resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + required: + - name + type: object + required: + - mountPath + - role + type: object + ldap: + description: |- + Ldap authenticates with Vault by passing username/password pair using + the LDAP authentication method + properties: + path: + default: ldap + description: |- + Path where the LDAP authentication backend is mounted + in Vault, e.g: "ldap" + type: string + secretRef: + description: |- + SecretRef to a key in a Secret resource containing password for the LDAP + user used to authenticate with Vault using the LDAP authentication + method + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + username: + description: |- + Username is a LDAP user name used to authenticate using the LDAP Vault + authentication method + type: string + required: + - path + - username + type: object + tokenSecretRef: + description: TokenSecretRef authenticates with Vault by presenting a token. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + caBundle: + description: |- + PEM encoded CA bundle used to validate Vault server certificate. Only used + if the Server URL is using HTTPS protocol. This parameter is ignored for + plain HTTP protocol connection. If not set the system root certificates + are used to validate the TLS connection. + format: byte + type: string + caProvider: + description: The provider for the CA bundle to use to validate Vault server certificate. + properties: + key: + description: The key the value inside of the provider type to use, only used with "Secret" type + type: string + name: + description: The name of the object located at the provider type. + type: string + namespace: + description: The namespace the Provider type is in. + type: string + type: + description: The type of provider to use such as "Secret", or "ConfigMap". + enum: + - Secret + - ConfigMap + type: string + required: + - name + - type + type: object + forwardInconsistent: + description: |- + ForwardInconsistent tells Vault to forward read-after-write requests to the Vault + leader instead of simply retrying within a loop. This can increase performance if + the option is enabled serverside. + https://www.vaultproject.io/docs/configuration/replication#allow_forwarding_via_header + type: boolean + namespace: + description: |- + Name of the vault namespace. Namespaces is a set of features within Vault Enterprise that allows + Vault environments to support Secure Multi-tenancy. e.g: "ns1". + More about namespaces can be found here https://www.vaultproject.io/docs/enterprise/namespaces + type: string + path: + description: |- + Path is the mount path of the Vault KV backend endpoint, e.g: + "secret". The v2 KV secret engine version specific "/data" path suffix + for fetching secrets from Vault is optional and will be appended + if not present in specified path. + type: string + readYourWrites: + description: |- + ReadYourWrites ensures isolated read-after-write semantics by + providing discovered cluster replication states in each request. + More information about eventual consistency in Vault can be found here + https://www.vaultproject.io/docs/enterprise/consistency + type: boolean + server: + description: 'Server is the connection address for the Vault server, e.g: "https://vault.example.com:8200".' + type: string + version: + default: v2 + description: |- + Version is the Vault KV secret engine version. This can be either "v1" or + "v2". Version defaults to "v2". + enum: + - v1 + - v2 + type: string + required: + - auth + - server + type: object + webhook: + description: Webhook configures this store to sync secrets using a generic templated webhook + properties: + body: + description: Body + type: string + caBundle: + description: |- + PEM encoded CA bundle used to validate webhook server certificate. Only used + if the Server URL is using HTTPS protocol. This parameter is ignored for + plain HTTP protocol connection. If not set the system root certificates + are used to validate the TLS connection. + format: byte + type: string + caProvider: + description: The provider for the CA bundle to use to validate webhook server certificate. + properties: + key: + description: The key the value inside of the provider type to use, only used with "Secret" type + type: string + name: + description: The name of the object located at the provider type. + type: string + namespace: + description: The namespace the Provider type is in. + type: string + type: + description: The type of provider to use such as "Secret", or "ConfigMap". + enum: + - Secret + - ConfigMap + type: string + required: + - name + - type + type: object + headers: + additionalProperties: + type: string + description: Headers + type: object + method: + description: Webhook Method + type: string + result: + description: Result formatting + properties: + jsonPath: + description: Json path of return value + type: string + type: object + secrets: + description: |- + Secrets to fill in templates + These secrets will be passed to the templating function as key value pairs under the given name + items: + properties: + name: + description: Name of this secret in templates + type: string + secretRef: + description: Secret ref to fill in credentials + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + required: + - name + - secretRef + type: object + type: array + timeout: + description: Timeout + type: string + url: + description: Webhook url to call + type: string + required: + - result + - url + type: object + yandexlockbox: + description: YandexLockbox configures this store to sync secrets using Yandex Lockbox provider + properties: + apiEndpoint: + description: Yandex.Cloud API endpoint (e.g. 'api.cloud.yandex.net:443') + type: string + auth: + description: Auth defines the information necessary to authenticate against Yandex Lockbox + properties: + authorizedKeySecretRef: + description: The authorized key used for authentication + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + caProvider: + description: The provider for the CA bundle to use to validate Yandex.Cloud server certificate. + properties: + certSecretRef: + description: |- + A reference to a specific 'key' within a Secret resource, + In some instances, `key` is a required field. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + required: + - auth + type: object + type: object + retrySettings: + description: Used to configure http retries if failed + properties: + maxRetries: + format: int32 + type: integer + retryInterval: + type: string + type: object + required: + - provider + type: object + status: + description: SecretStoreStatus defines the observed state of the SecretStore. + properties: + conditions: + items: + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + required: + - status + - type + type: object + type: array + type: object + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: AGE + type: date + - jsonPath: .status.conditions[?(@.type=="Ready")].reason + name: Status + type: string + - jsonPath: .status.capabilities + name: Capabilities + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: SecretStore represents a secure external location for storing secrets, which can be referenced as part of `storeRef` fields. + 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: SecretStoreSpec defines the desired state of SecretStore. + properties: + conditions: + description: Used to constraint a ClusterSecretStore to specific namespaces. Relevant only to ClusterSecretStore + items: + description: |- + ClusterSecretStoreCondition describes a condition by which to choose namespaces to process ExternalSecrets in + for a ClusterSecretStore instance. + properties: + namespaceRegexes: + description: Choose namespaces by using regex matching + items: + type: string + type: array + namespaceSelector: + description: Choose namespace using a labelSelector + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Choose namespaces by name + items: + type: string + type: array + type: object + type: array + controller: + description: |- + Used to select the correct ESO controller (think: ingress.ingressClassName) + The ESO controller is instantiated with a specific controller name and filters ES based on this property + type: string + provider: + description: Used to configure the provider. Only one provider may be set + maxProperties: 1 + minProperties: 1 + properties: + akeyless: + description: Akeyless configures this store to sync secrets using Akeyless Vault provider + properties: + akeylessGWApiURL: + description: Akeyless GW API Url from which the secrets to be fetched from. + type: string + authSecretRef: + description: Auth configures how the operator authenticates with Akeyless. + properties: + kubernetesAuth: + description: |- + Kubernetes authenticates with Akeyless by passing the ServiceAccount + token stored in the named Secret resource. + properties: + accessID: + description: the Akeyless Kubernetes auth-method access-id + type: string + k8sConfName: + description: Kubernetes-auth configuration name in Akeyless-Gateway + type: string + secretRef: + description: |- + Optional secret field containing a Kubernetes ServiceAccount JWT used + for authenticating with Akeyless. If a name is specified without a key, + `token` is the default. If one is not specified, the one bound to + the controller will be used. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + serviceAccountRef: + description: |- + Optional service account field containing the name of a kubernetes ServiceAccount. + If the service account is specified, the service account secret token JWT will be used + for authenticating with Akeyless. If the service account selector is not supplied, + the secretRef will be used instead. + properties: + audiences: + description: |- + Audience specifies the `aud` claim for the service account token + If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity + then this audiences will be appended to the list + items: + type: string + type: array + name: + description: The name of the ServiceAccount resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + required: + - name + type: object + required: + - accessID + - k8sConfName + type: object + secretRef: + description: |- + Reference to a Secret that contains the details + to authenticate with Akeyless. + properties: + accessID: + description: The SecretAccessID is used for authentication + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + accessType: + description: |- + A reference to a specific 'key' within a Secret resource, + In some instances, `key` is a required field. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + accessTypeParam: + description: |- + A reference to a specific 'key' within a Secret resource, + In some instances, `key` is a required field. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + type: object + caBundle: + description: |- + PEM/base64 encoded CA bundle used to validate Akeyless Gateway certificate. Only used + if the AkeylessGWApiURL URL is using HTTPS protocol. If not set the system root certificates + are used to validate the TLS connection. + format: byte + type: string + caProvider: + description: The provider for the CA bundle to use to validate Akeyless Gateway certificate. + properties: + key: + description: The key where the CA certificate can be found in the Secret or ConfigMap. + type: string + name: + description: The name of the object located at the provider type. + type: string + namespace: + description: |- + The namespace the Provider type is in. + Can only be defined when used in a ClusterSecretStore. + type: string + type: + description: The type of provider to use such as "Secret", or "ConfigMap". + enum: + - Secret + - ConfigMap + type: string + required: + - name + - type + type: object + required: + - akeylessGWApiURL + - authSecretRef + type: object + alibaba: + description: Alibaba configures this store to sync secrets using Alibaba Cloud provider + properties: + auth: + description: AlibabaAuth contains a secretRef for credentials. + properties: + rrsa: + description: Authenticate against Alibaba using RRSA. + properties: + oidcProviderArn: + type: string + oidcTokenFilePath: + type: string + roleArn: + type: string + sessionName: + type: string + required: + - oidcProviderArn + - oidcTokenFilePath + - roleArn + - sessionName + type: object + secretRef: + description: AlibabaAuthSecretRef holds secret references for Alibaba credentials. + properties: + accessKeyIDSecretRef: + description: The AccessKeyID is used for authentication + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + accessKeySecretSecretRef: + description: The AccessKeySecret is used for authentication + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + required: + - accessKeyIDSecretRef + - accessKeySecretSecretRef + type: object + type: object + regionID: + description: Alibaba Region to be used for the provider + type: string + required: + - auth + - regionID + type: object + aws: + description: AWS configures this store to sync secrets using AWS Secret Manager provider + properties: + additionalRoles: + description: AdditionalRoles is a chained list of Role ARNs which the provider will sequentially assume before assuming the Role + items: + type: string + type: array + auth: + description: |- + Auth defines the information necessary to authenticate against AWS + if not set aws sdk will infer credentials from your environment + see: https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials + properties: + jwt: + description: Authenticate against AWS using service account tokens. + properties: + serviceAccountRef: + description: A reference to a ServiceAccount resource. + properties: + audiences: + description: |- + Audience specifies the `aud` claim for the service account token + If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity + then this audiences will be appended to the list + items: + type: string + type: array + name: + description: The name of the ServiceAccount resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + required: + - name + type: object + type: object + secretRef: + description: |- + AWSAuthSecretRef holds secret references for AWS credentials + both AccessKeyID and SecretAccessKey must be defined in order to properly authenticate. + properties: + accessKeyIDSecretRef: + description: The AccessKeyID is used for authentication + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + secretAccessKeySecretRef: + description: The SecretAccessKey is used for authentication + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + sessionTokenSecretRef: + description: |- + The SessionToken used for authentication + This must be defined if AccessKeyID and SecretAccessKey are temporary credentials + see: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + type: object + externalID: + description: AWS External ID set on assumed IAM roles + type: string + prefix: + description: Prefix adds a prefix to all retrieved values. + type: string + region: + description: AWS Region to be used for the provider + type: string + role: + description: Role is a Role ARN which the provider will assume + type: string + secretsManager: + description: SecretsManager defines how the provider behaves when interacting with AWS SecretsManager + properties: + forceDeleteWithoutRecovery: + description: |- + Specifies whether to delete the secret without any recovery window. You + can't use both this parameter and RecoveryWindowInDays in the same call. + If you don't use either, then by default Secrets Manager uses a 30 day + recovery window. + see: https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_DeleteSecret.html#SecretsManager-DeleteSecret-request-ForceDeleteWithoutRecovery + type: boolean + recoveryWindowInDays: + description: |- + The number of days from 7 to 30 that Secrets Manager waits before + permanently deleting the secret. You can't use both this parameter and + ForceDeleteWithoutRecovery in the same call. If you don't use either, + then by default Secrets Manager uses a 30 day recovery window. + see: https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_DeleteSecret.html#SecretsManager-DeleteSecret-request-RecoveryWindowInDays + format: int64 + type: integer + type: object + service: + description: Service defines which service should be used to fetch the secrets + enum: + - SecretsManager + - ParameterStore + type: string + sessionTags: + description: AWS STS assume role session tags + items: + properties: + key: + type: string + value: + type: string + required: + - key + - value + type: object + type: array + transitiveTagKeys: + description: AWS STS assume role transitive session tags. Required when multiple rules are used with the provider + items: + type: string + type: array + required: + - region + - service + type: object + azurekv: + description: AzureKV configures this store to sync secrets using Azure Key Vault provider + properties: + authSecretRef: + description: Auth configures how the operator authenticates with Azure. Required for ServicePrincipal auth type. Optional for WorkloadIdentity. + properties: + clientCertificate: + description: The Azure ClientCertificate of the service principle used for authentication. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + clientId: + description: The Azure clientId of the service principle or managed identity used for authentication. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + clientSecret: + description: The Azure ClientSecret of the service principle used for authentication. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + tenantId: + description: The Azure tenantId of the managed identity used for authentication. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + authType: + default: ServicePrincipal + description: |- + Auth type defines how to authenticate to the keyvault service. + Valid values are: + - "ServicePrincipal" (default): Using a service principal (tenantId, clientId, clientSecret) + - "ManagedIdentity": Using Managed Identity assigned to the pod (see aad-pod-identity) + enum: + - ServicePrincipal + - ManagedIdentity + - WorkloadIdentity + type: string + environmentType: + default: PublicCloud + description: |- + EnvironmentType specifies the Azure cloud environment endpoints to use for + connecting and authenticating with Azure. By default it points to the public cloud AAD endpoint. + The following endpoints are available, also see here: https://github.com/Azure/go-autorest/blob/main/autorest/azure/environments.go#L152 + PublicCloud, USGovernmentCloud, ChinaCloud, GermanCloud + enum: + - PublicCloud + - USGovernmentCloud + - ChinaCloud + - GermanCloud + type: string + identityId: + description: If multiple Managed Identity is assigned to the pod, you can select the one to be used + type: string + serviceAccountRef: + description: |- + ServiceAccountRef specified the service account + that should be used when authenticating with WorkloadIdentity. + properties: + audiences: + description: |- + Audience specifies the `aud` claim for the service account token + If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity + then this audiences will be appended to the list + items: + type: string + type: array + name: + description: The name of the ServiceAccount resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + required: + - name + type: object + tenantId: + description: TenantID configures the Azure Tenant to send requests to. Required for ServicePrincipal auth type. Optional for WorkloadIdentity. + type: string + vaultUrl: + description: Vault Url from which the secrets to be fetched from. + type: string + required: + - vaultUrl + type: object + beyondtrust: + description: Beyondtrust configures this store to sync secrets using Password Safe provider. + properties: + auth: + description: Auth configures how the operator authenticates with Beyondtrust. + properties: + certificate: + description: Content of the certificate (cert.pem) for use when authenticating with an OAuth client Id using a Client Certificate. + properties: + secretRef: + description: SecretRef references a key in a secret that will be used as value. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + value: + description: Value can be specified directly to set a value without using a secret. + type: string + type: object + certificateKey: + description: Certificate private key (key.pem). For use when authenticating with an OAuth client Id + properties: + secretRef: + description: SecretRef references a key in a secret that will be used as value. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + value: + description: Value can be specified directly to set a value without using a secret. + type: string + type: object + clientId: + properties: + secretRef: + description: SecretRef references a key in a secret that will be used as value. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + value: + description: Value can be specified directly to set a value without using a secret. + type: string + type: object + clientSecret: + properties: + secretRef: + description: SecretRef references a key in a secret that will be used as value. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + value: + description: Value can be specified directly to set a value without using a secret. + type: string + type: object + required: + - clientId + - clientSecret + type: object + server: + description: Auth configures how API server works. + properties: + apiUrl: + type: string + clientTimeOutSeconds: + description: Timeout specifies a time limit for requests made by this Client. The timeout includes connection time, any redirects, and reading the response body. Defaults to 45 seconds. + type: integer + retrievalType: + description: The secret retrieval type. SECRET = Secrets Safe (credential, text, file). MANAGED_ACCOUNT = Password Safe account associated with a system. + type: string + separator: + description: A character that separates the folder names. + type: string + verifyCA: + type: boolean + required: + - apiUrl + - verifyCA + type: object + required: + - auth + - server + type: object + bitwardensecretsmanager: + description: BitwardenSecretsManager configures this store to sync secrets using BitwardenSecretsManager provider + properties: + apiURL: + type: string + auth: + description: |- + Auth configures how secret-manager authenticates with a bitwarden machine account instance. + Make sure that the token being used has permissions on the given secret. + properties: + secretRef: + description: BitwardenSecretsManagerSecretRef contains the credential ref to the bitwarden instance. + properties: + credentials: + description: AccessToken used for the bitwarden instance. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + required: + - credentials + type: object + required: + - secretRef + type: object + bitwardenServerSDKURL: + type: string + caBundle: + description: |- + Base64 encoded certificate for the bitwarden server sdk. The sdk MUST run with HTTPS to make sure no MITM attack + can be performed. + type: string + caProvider: + description: 'see: https://external-secrets.io/latest/spec/#external-secrets.io/v1alpha1.CAProvider' + properties: + key: + description: The key where the CA certificate can be found in the Secret or ConfigMap. + type: string + name: + description: The name of the object located at the provider type. + type: string + namespace: + description: |- + The namespace the Provider type is in. + Can only be defined when used in a ClusterSecretStore. + type: string + type: + description: The type of provider to use such as "Secret", or "ConfigMap". + enum: + - Secret + - ConfigMap + type: string + required: + - name + - type + type: object + identityURL: + type: string + organizationID: + description: OrganizationID determines which organization this secret store manages. + type: string + projectID: + description: ProjectID determines which project this secret store manages. + type: string + required: + - auth + - organizationID + - projectID + type: object + chef: + description: Chef configures this store to sync secrets with chef server + properties: + auth: + description: Auth defines the information necessary to authenticate against chef Server + properties: + secretRef: + description: ChefAuthSecretRef holds secret references for chef server login credentials. + properties: + privateKeySecretRef: + description: SecretKey is the Signing Key in PEM format, used for authentication. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + required: + - privateKeySecretRef + type: object + required: + - secretRef + type: object + serverUrl: + description: ServerURL is the chef server URL used to connect to. If using orgs you should include your org in the url and terminate the url with a "/" + type: string + username: + description: UserName should be the user ID on the chef server + type: string + required: + - auth + - serverUrl + - username + type: object + conjur: + description: Conjur configures this store to sync secrets using conjur provider + properties: + auth: + properties: + apikey: + properties: + account: + type: string + apiKeyRef: + description: |- + A reference to a specific 'key' within a Secret resource, + In some instances, `key` is a required field. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + userRef: + description: |- + A reference to a specific 'key' within a Secret resource, + In some instances, `key` is a required field. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + required: + - account + - apiKeyRef + - userRef + type: object + jwt: + properties: + account: + type: string + hostId: + description: |- + Optional HostID for JWT authentication. This may be used depending + on how the Conjur JWT authenticator policy is configured. + type: string + secretRef: + description: |- + Optional SecretRef that refers to a key in a Secret resource containing JWT token to + authenticate with Conjur using the JWT authentication method. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + serviceAccountRef: + description: |- + Optional ServiceAccountRef specifies the Kubernetes service account for which to request + a token for with the `TokenRequest` API. + properties: + audiences: + description: |- + Audience specifies the `aud` claim for the service account token + If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity + then this audiences will be appended to the list + items: + type: string + type: array + name: + description: The name of the ServiceAccount resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + required: + - name + type: object + serviceID: + description: The conjur authn jwt webservice id + type: string + required: + - account + - serviceID + type: object + type: object + caBundle: + type: string + caProvider: + description: |- + Used to provide custom certificate authority (CA) certificates + for a secret store. The CAProvider points to a Secret or ConfigMap resource + that contains a PEM-encoded certificate. + properties: + key: + description: The key where the CA certificate can be found in the Secret or ConfigMap. + type: string + name: + description: The name of the object located at the provider type. + type: string + namespace: + description: |- + The namespace the Provider type is in. + Can only be defined when used in a ClusterSecretStore. + type: string + type: + description: The type of provider to use such as "Secret", or "ConfigMap". + enum: + - Secret + - ConfigMap + type: string + required: + - name + - type + type: object + url: + type: string + required: + - auth + - url + type: object + delinea: + description: |- + Delinea DevOps Secrets Vault + https://docs.delinea.com/online-help/products/devops-secrets-vault/current + properties: + clientId: + description: ClientID is the non-secret part of the credential. + properties: + secretRef: + description: SecretRef references a key in a secret that will be used as value. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + value: + description: Value can be specified directly to set a value without using a secret. + type: string + type: object + clientSecret: + description: ClientSecret is the secret part of the credential. + properties: + secretRef: + description: SecretRef references a key in a secret that will be used as value. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + value: + description: Value can be specified directly to set a value without using a secret. + type: string + type: object + tenant: + description: Tenant is the chosen hostname / site name. + type: string + tld: + description: |- + TLD is based on the server location that was chosen during provisioning. + If unset, defaults to "com". + type: string + urlTemplate: + description: |- + URLTemplate + If unset, defaults to "https://%s.secretsvaultcloud.%s/v1/%s%s". + type: string + required: + - clientId + - clientSecret + - tenant + type: object + device42: + description: Device42 configures this store to sync secrets using the Device42 provider + properties: + auth: + description: Auth configures how secret-manager authenticates with a Device42 instance. + properties: + secretRef: + properties: + credentials: + description: Username / Password is used for authentication. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + required: + - secretRef + type: object + host: + description: URL configures the Device42 instance URL. + type: string + required: + - auth + - host + type: object + doppler: + description: Doppler configures this store to sync secrets using the Doppler provider + properties: + auth: + description: Auth configures how the Operator authenticates with the Doppler API + properties: + secretRef: + properties: + dopplerToken: + description: |- + The DopplerToken is used for authentication. + See https://docs.doppler.com/reference/api#authentication for auth token types. + The Key attribute defaults to dopplerToken if not specified. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + required: + - dopplerToken + type: object + required: + - secretRef + type: object + config: + description: Doppler config (required if not using a Service Token) + type: string + format: + description: Format enables the downloading of secrets as a file (string) + enum: + - json + - dotnet-json + - env + - yaml + - docker + type: string + nameTransformer: + description: Environment variable compatible name transforms that change secret names to a different format + enum: + - upper-camel + - camel + - lower-snake + - tf-var + - dotnet-env + - lower-kebab + type: string + project: + description: Doppler project (required if not using a Service Token) + type: string + required: + - auth + type: object + fake: + description: Fake configures a store with static key/value pairs + properties: + data: + items: + properties: + key: + type: string + value: + type: string + valueMap: + additionalProperties: + type: string + description: 'Deprecated: ValueMap is deprecated and is intended to be removed in the future, use the `value` field instead.' + type: object + version: + type: string + required: + - key + type: object + type: array + required: + - data + type: object + fortanix: + description: Fortanix configures this store to sync secrets using the Fortanix provider + properties: + apiKey: + description: APIKey is the API token to access SDKMS Applications. + properties: + secretRef: + description: SecretRef is a reference to a secret containing the SDKMS API Key. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + apiUrl: + description: APIURL is the URL of SDKMS API. Defaults to `sdkms.fortanix.com`. + type: string + type: object + gcpsm: + description: GCPSM configures this store to sync secrets using Google Cloud Platform Secret Manager provider + properties: + auth: + description: Auth defines the information necessary to authenticate against GCP + properties: + secretRef: + properties: + secretAccessKeySecretRef: + description: The SecretAccessKey is used for authentication + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + workloadIdentity: + properties: + clusterLocation: + type: string + clusterName: + type: string + clusterProjectID: + type: string + serviceAccountRef: + description: A reference to a ServiceAccount resource. + properties: + audiences: + description: |- + Audience specifies the `aud` claim for the service account token + If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity + then this audiences will be appended to the list + items: + type: string + type: array + name: + description: The name of the ServiceAccount resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + required: + - name + type: object + required: + - clusterLocation + - clusterName + - serviceAccountRef + type: object + type: object + location: + description: Location optionally defines a location for a secret + type: string + projectID: + description: ProjectID project where secret is located + type: string + type: object + gitlab: + description: GitLab configures this store to sync secrets using GitLab Variables provider + properties: + auth: + description: Auth configures how secret-manager authenticates with a GitLab instance. + properties: + SecretRef: + properties: + accessToken: + description: AccessToken is used for authentication. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + required: + - SecretRef + type: object + environment: + description: Environment environment_scope of gitlab CI/CD variables (Please see https://docs.gitlab.com/ee/ci/environments/#create-a-static-environment on how to create environments) + type: string + groupIDs: + description: GroupIDs specify, which gitlab groups to pull secrets from. Group secrets are read from left to right followed by the project variables. + items: + type: string + type: array + inheritFromGroups: + description: InheritFromGroups specifies whether parent groups should be discovered and checked for secrets. + type: boolean + projectID: + description: ProjectID specifies a project where secrets are located. + type: string + url: + description: URL configures the GitLab instance URL. Defaults to https://gitlab.com/. + type: string + required: + - auth + type: object + ibm: + description: IBM configures this store to sync secrets using IBM Cloud provider + properties: + auth: + description: Auth configures how secret-manager authenticates with the IBM secrets manager. + maxProperties: 1 + minProperties: 1 + properties: + containerAuth: + description: IBM Container-based auth with IAM Trusted Profile. + properties: + iamEndpoint: + type: string + profile: + description: the IBM Trusted Profile + type: string + tokenLocation: + description: Location the token is mounted on the pod + type: string + required: + - profile + type: object + secretRef: + properties: + secretApiKeySecretRef: + description: The SecretAccessKey is used for authentication + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + type: object + serviceUrl: + description: ServiceURL is the Endpoint URL that is specific to the Secrets Manager service instance + type: string + required: + - auth + type: object + infisical: + description: Infisical configures this store to sync secrets using the Infisical provider + properties: + auth: + description: Auth configures how the Operator authenticates with the Infisical API + properties: + universalAuthCredentials: + properties: + clientId: + description: |- + A reference to a specific 'key' within a Secret resource, + In some instances, `key` is a required field. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + clientSecret: + description: |- + A reference to a specific 'key' within a Secret resource, + In some instances, `key` is a required field. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + required: + - clientId + - clientSecret + type: object + type: object + hostAPI: + default: https://app.infisical.com/api + type: string + secretsScope: + properties: + environmentSlug: + type: string + projectSlug: + type: string + secretsPath: + default: / + type: string + required: + - environmentSlug + - projectSlug + type: object + required: + - auth + - secretsScope + type: object + keepersecurity: + description: KeeperSecurity configures this store to sync secrets using the KeeperSecurity provider + properties: + authRef: + description: |- + A reference to a specific 'key' within a Secret resource, + In some instances, `key` is a required field. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + folderID: + type: string + required: + - authRef + - folderID + type: object + kubernetes: + description: Kubernetes configures this store to sync secrets using a Kubernetes cluster provider + properties: + auth: + description: Auth configures how secret-manager authenticates with a Kubernetes instance. + maxProperties: 1 + minProperties: 1 + properties: + cert: + description: has both clientCert and clientKey as secretKeySelector + properties: + clientCert: + description: |- + A reference to a specific 'key' within a Secret resource, + In some instances, `key` is a required field. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + clientKey: + description: |- + A reference to a specific 'key' within a Secret resource, + In some instances, `key` is a required field. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + serviceAccount: + description: points to a service account that should be used for authentication + properties: + audiences: + description: |- + Audience specifies the `aud` claim for the service account token + If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity + then this audiences will be appended to the list + items: + type: string + type: array + name: + description: The name of the ServiceAccount resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + required: + - name + type: object + token: + description: use static token to authenticate with + properties: + bearerToken: + description: |- + A reference to a specific 'key' within a Secret resource, + In some instances, `key` is a required field. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + type: object + authRef: + description: A reference to a secret that contains the auth information. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + remoteNamespace: + default: default + description: Remote namespace to fetch the secrets from + type: string + server: + description: configures the Kubernetes server Address. + properties: + caBundle: + description: CABundle is a base64-encoded CA certificate + format: byte + type: string + caProvider: + description: 'see: https://external-secrets.io/v0.4.1/spec/#external-secrets.io/v1alpha1.CAProvider' + properties: + key: + description: The key where the CA certificate can be found in the Secret or ConfigMap. + type: string + name: + description: The name of the object located at the provider type. + type: string + namespace: + description: |- + The namespace the Provider type is in. + Can only be defined when used in a ClusterSecretStore. + type: string + type: + description: The type of provider to use such as "Secret", or "ConfigMap". + enum: + - Secret + - ConfigMap + type: string + required: + - name + - type + type: object + url: + default: kubernetes.default + description: configures the Kubernetes server Address. + type: string + type: object + type: object + onboardbase: + description: Onboardbase configures this store to sync secrets using the Onboardbase provider + properties: + apiHost: + default: https://public.onboardbase.com/api/v1/ + description: APIHost use this to configure the host url for the API for selfhosted installation, default is https://public.onboardbase.com/api/v1/ + type: string + auth: + description: Auth configures how the Operator authenticates with the Onboardbase API + properties: + apiKeyRef: + description: |- + OnboardbaseAPIKey is the APIKey generated by an admin account. + It is used to recognize and authorize access to a project and environment within onboardbase + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + passcodeRef: + description: OnboardbasePasscode is the passcode attached to the API Key + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + required: + - apiKeyRef + - passcodeRef + type: object + environment: + default: development + description: Environment is the name of an environmnent within a project to pull the secrets from + type: string + project: + default: development + description: Project is an onboardbase project that the secrets should be pulled from + type: string + required: + - apiHost + - auth + - environment + - project + type: object + onepassword: + description: OnePassword configures this store to sync secrets using the 1Password Cloud provider + properties: + auth: + description: Auth defines the information necessary to authenticate against OnePassword Connect Server + properties: + secretRef: + description: OnePasswordAuthSecretRef holds secret references for 1Password credentials. + properties: + connectTokenSecretRef: + description: The ConnectToken is used for authentication to a 1Password Connect Server. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + required: + - connectTokenSecretRef + type: object + required: + - secretRef + type: object + connectHost: + description: ConnectHost defines the OnePassword Connect Server to connect to + type: string + vaults: + additionalProperties: + type: integer + description: Vaults defines which OnePassword vaults to search in which order + type: object + required: + - auth + - connectHost + - vaults + type: object + oracle: + description: Oracle configures this store to sync secrets using Oracle Vault provider + properties: + auth: + description: |- + Auth configures how secret-manager authenticates with the Oracle Vault. + If empty, use the instance principal, otherwise the user credentials specified in Auth. + properties: + secretRef: + description: SecretRef to pass through sensitive information. + properties: + fingerprint: + description: Fingerprint is the fingerprint of the API private key. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + privatekey: + description: PrivateKey is the user's API Signing Key in PEM format, used for authentication. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + required: + - fingerprint + - privatekey + type: object + tenancy: + description: Tenancy is the tenancy OCID where user is located. + type: string + user: + description: User is an access OCID specific to the account. + type: string + required: + - secretRef + - tenancy + - user + type: object + compartment: + description: |- + Compartment is the vault compartment OCID. + Required for PushSecret + type: string + encryptionKey: + description: |- + EncryptionKey is the OCID of the encryption key within the vault. + Required for PushSecret + type: string + principalType: + description: |- + The type of principal to use for authentication. If left blank, the Auth struct will + determine the principal type. This optional field must be specified if using + workload identity. + enum: + - "" + - UserPrincipal + - InstancePrincipal + - Workload + type: string + region: + description: Region is the region where vault is located. + type: string + serviceAccountRef: + description: |- + ServiceAccountRef specified the service account + that should be used when authenticating with WorkloadIdentity. + properties: + audiences: + description: |- + Audience specifies the `aud` claim for the service account token + If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity + then this audiences will be appended to the list + items: + type: string + type: array + name: + description: The name of the ServiceAccount resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + required: + - name + type: object + vault: + description: Vault is the vault's OCID of the specific vault where secret is located. + type: string + required: + - region + - vault + type: object + passbolt: + properties: + auth: + description: Auth defines the information necessary to authenticate against Passbolt Server + properties: + passwordSecretRef: + description: |- + A reference to a specific 'key' within a Secret resource, + In some instances, `key` is a required field. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + privateKeySecretRef: + description: |- + A reference to a specific 'key' within a Secret resource, + In some instances, `key` is a required field. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + required: + - passwordSecretRef + - privateKeySecretRef + type: object + host: + description: Host defines the Passbolt Server to connect to + type: string + required: + - auth + - host + type: object + passworddepot: + description: Configures a store to sync secrets with a Password Depot instance. + properties: + auth: + description: Auth configures how secret-manager authenticates with a Password Depot instance. + properties: + secretRef: + properties: + credentials: + description: Username / Password is used for authentication. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + required: + - secretRef + type: object + database: + description: Database to use as source + type: string + host: + description: URL configures the Password Depot instance URL. + type: string + required: + - auth + - database + - host + type: object + pulumi: + description: Pulumi configures this store to sync secrets using the Pulumi provider + properties: + accessToken: + description: AccessToken is the access tokens to sign in to the Pulumi Cloud Console. + properties: + secretRef: + description: SecretRef is a reference to a secret containing the Pulumi API token. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + apiUrl: + default: https://api.pulumi.com/api/preview + description: APIURL is the URL of the Pulumi API. + type: string + environment: + description: |- + Environment are YAML documents composed of static key-value pairs, programmatic expressions, + dynamically retrieved values from supported providers including all major clouds, + and other Pulumi ESC environments. + To create a new environment, visit https://www.pulumi.com/docs/esc/environments/ for more information. + type: string + organization: + description: |- + Organization are a space to collaborate on shared projects and stacks. + To create a new organization, visit https://app.pulumi.com/ and click "New Organization". + type: string + required: + - accessToken + - environment + - organization + type: object + scaleway: + description: Scaleway + properties: + accessKey: + description: AccessKey is the non-secret part of the api key. + properties: + secretRef: + description: SecretRef references a key in a secret that will be used as value. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + value: + description: Value can be specified directly to set a value without using a secret. + type: string + type: object + apiUrl: + description: APIURL is the url of the api to use. Defaults to https://api.scaleway.com + type: string + projectId: + description: 'ProjectID is the id of your project, which you can find in the console: https://console.scaleway.com/project/settings' + type: string + region: + description: 'Region where your secrets are located: https://developers.scaleway.com/en/quickstart/#region-and-zone' + type: string + secretKey: + description: SecretKey is the non-secret part of the api key. + properties: + secretRef: + description: SecretRef references a key in a secret that will be used as value. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + value: + description: Value can be specified directly to set a value without using a secret. + type: string + type: object + required: + - accessKey + - projectId + - region + - secretKey + type: object + secretserver: + description: |- + SecretServer configures this store to sync secrets using SecretServer provider + https://docs.delinea.com/online-help/secret-server/start.htm + properties: + password: + description: Password is the secret server account password. + properties: + secretRef: + description: SecretRef references a key in a secret that will be used as value. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + value: + description: Value can be specified directly to set a value without using a secret. + type: string + type: object + serverURL: + description: |- + ServerURL + URL to your secret server installation + type: string + username: + description: Username is the secret server account username. + properties: + secretRef: + description: SecretRef references a key in a secret that will be used as value. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + value: + description: Value can be specified directly to set a value without using a secret. + type: string + type: object + required: + - password + - serverURL + - username + type: object + senhasegura: + description: Senhasegura configures this store to sync secrets using senhasegura provider + properties: + auth: + description: Auth defines parameters to authenticate in senhasegura + properties: + clientId: + type: string + clientSecretSecretRef: + description: |- + A reference to a specific 'key' within a Secret resource, + In some instances, `key` is a required field. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + required: + - clientId + - clientSecretSecretRef + type: object + ignoreSslCertificate: + default: false + description: IgnoreSslCertificate defines if SSL certificate must be ignored + type: boolean + module: + description: Module defines which senhasegura module should be used to get secrets + type: string + url: + description: URL of senhasegura + type: string + required: + - auth + - module + - url + type: object + vault: + description: Vault configures this store to sync secrets using Hashi provider + properties: + auth: + description: Auth configures how secret-manager authenticates with the Vault server. + properties: + appRole: + description: |- + AppRole authenticates with Vault using the App Role auth mechanism, + with the role and secret stored in a Kubernetes Secret resource. + properties: + path: + default: approle + description: |- + Path where the App Role authentication backend is mounted + in Vault, e.g: "approle" + type: string + roleId: + description: |- + RoleID configured in the App Role authentication backend when setting + up the authentication backend in Vault. + type: string + roleRef: + description: |- + Reference to a key in a Secret that contains the App Role ID used + to authenticate with Vault. + The `key` field must be specified and denotes which entry within the Secret + resource is used as the app role id. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + secretRef: + description: |- + Reference to a key in a Secret that contains the App Role secret used + to authenticate with Vault. + The `key` field must be specified and denotes which entry within the Secret + resource is used as the app role secret. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + required: + - path + - secretRef + type: object + cert: + description: |- + Cert authenticates with TLS Certificates by passing client certificate, private key and ca certificate + Cert authentication method + properties: + clientCert: + description: |- + ClientCert is a certificate to authenticate using the Cert Vault + authentication method + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + secretRef: + description: |- + SecretRef to a key in a Secret resource containing client private key to + authenticate with Vault using the Cert authentication method + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + iam: + description: |- + Iam authenticates with vault by passing a special AWS request signed with AWS IAM credentials + AWS IAM authentication method + properties: + externalID: + description: AWS External ID set on assumed IAM roles + type: string + jwt: + description: Specify a service account with IRSA enabled + properties: + serviceAccountRef: + description: A reference to a ServiceAccount resource. + properties: + audiences: + description: |- + Audience specifies the `aud` claim for the service account token + If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity + then this audiences will be appended to the list + items: + type: string + type: array + name: + description: The name of the ServiceAccount resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + required: + - name + type: object + type: object + path: + description: 'Path where the AWS auth method is enabled in Vault, e.g: "aws"' + type: string + region: + description: AWS region + type: string + role: + description: This is the AWS role to be assumed before talking to vault + type: string + secretRef: + description: Specify credentials in a Secret object + properties: + accessKeyIDSecretRef: + description: The AccessKeyID is used for authentication + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + secretAccessKeySecretRef: + description: The SecretAccessKey is used for authentication + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + sessionTokenSecretRef: + description: |- + The SessionToken used for authentication + This must be defined if AccessKeyID and SecretAccessKey are temporary credentials + see: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + vaultAwsIamServerID: + description: 'X-Vault-AWS-IAM-Server-ID is an additional header used by Vault IAM auth method to mitigate against different types of replay attacks. More details here: https://developer.hashicorp.com/vault/docs/auth/aws' + type: string + vaultRole: + description: Vault Role. In vault, a role describes an identity with a set of permissions, groups, or policies you want to attach a user of the secrets engine + type: string + required: + - vaultRole + type: object + jwt: + description: |- + Jwt authenticates with Vault by passing role and JWT token using the + JWT/OIDC authentication method + properties: + kubernetesServiceAccountToken: + description: |- + Optional ServiceAccountToken specifies the Kubernetes service account for which to request + a token for with the `TokenRequest` API. + properties: + audiences: + description: |- + Optional audiences field that will be used to request a temporary Kubernetes service + account token for the service account referenced by `serviceAccountRef`. + Defaults to a single audience `vault` it not specified. + Deprecated: use serviceAccountRef.Audiences instead + items: + type: string + type: array + expirationSeconds: + description: |- + Optional expiration time in seconds that will be used to request a temporary + Kubernetes service account token for the service account referenced by + `serviceAccountRef`. + Deprecated: this will be removed in the future. + Defaults to 10 minutes. + format: int64 + type: integer + serviceAccountRef: + description: Service account field containing the name of a kubernetes ServiceAccount. + properties: + audiences: + description: |- + Audience specifies the `aud` claim for the service account token + If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity + then this audiences will be appended to the list + items: + type: string + type: array + name: + description: The name of the ServiceAccount resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + required: + - name + type: object + required: + - serviceAccountRef + type: object + path: + default: jwt + description: |- + Path where the JWT authentication backend is mounted + in Vault, e.g: "jwt" + type: string + role: + description: |- + Role is a JWT role to authenticate using the JWT/OIDC Vault + authentication method + type: string + secretRef: + description: |- + Optional SecretRef that refers to a key in a Secret resource containing JWT token to + authenticate with Vault using the JWT/OIDC authentication method. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + required: + - path + type: object + kubernetes: + description: |- + Kubernetes authenticates with Vault by passing the ServiceAccount + token stored in the named Secret resource to the Vault server. + properties: + mountPath: + default: kubernetes + description: |- + Path where the Kubernetes authentication backend is mounted in Vault, e.g: + "kubernetes" + type: string + role: + description: |- + A required field containing the Vault Role to assume. A Role binds a + Kubernetes ServiceAccount with a set of Vault policies. + type: string + secretRef: + description: |- + Optional secret field containing a Kubernetes ServiceAccount JWT used + for authenticating with Vault. If a name is specified without a key, + `token` is the default. If one is not specified, the one bound to + the controller will be used. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + serviceAccountRef: + description: |- + Optional service account field containing the name of a kubernetes ServiceAccount. + If the service account is specified, the service account secret token JWT will be used + for authenticating with Vault. If the service account selector is not supplied, + the secretRef will be used instead. + properties: + audiences: + description: |- + Audience specifies the `aud` claim for the service account token + If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity + then this audiences will be appended to the list + items: + type: string + type: array + name: + description: The name of the ServiceAccount resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + required: + - name + type: object + required: + - mountPath + - role + type: object + ldap: + description: |- + Ldap authenticates with Vault by passing username/password pair using + the LDAP authentication method + properties: + path: + default: ldap + description: |- + Path where the LDAP authentication backend is mounted + in Vault, e.g: "ldap" + type: string + secretRef: + description: |- + SecretRef to a key in a Secret resource containing password for the LDAP + user used to authenticate with Vault using the LDAP authentication + method + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + username: + description: |- + Username is a LDAP user name used to authenticate using the LDAP Vault + authentication method + type: string + required: + - path + - username + type: object + namespace: + description: |- + Name of the vault namespace to authenticate to. This can be different than the namespace your secret is in. + Namespaces is a set of features within Vault Enterprise that allows + Vault environments to support Secure Multi-tenancy. e.g: "ns1". + More about namespaces can be found here https://www.vaultproject.io/docs/enterprise/namespaces + This will default to Vault.Namespace field if set, or empty otherwise + type: string + tokenSecretRef: + description: TokenSecretRef authenticates with Vault by presenting a token. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + userPass: + description: UserPass authenticates with Vault by passing username/password pair + properties: + path: + default: user + description: |- + Path where the UserPassword authentication backend is mounted + in Vault, e.g: "user" + type: string + secretRef: + description: |- + SecretRef to a key in a Secret resource containing password for the + user used to authenticate with Vault using the UserPass authentication + method + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + username: + description: |- + Username is a user name used to authenticate using the UserPass Vault + authentication method + type: string + required: + - path + - username + type: object + type: object + caBundle: + description: |- + PEM encoded CA bundle used to validate Vault server certificate. Only used + if the Server URL is using HTTPS protocol. This parameter is ignored for + plain HTTP protocol connection. If not set the system root certificates + are used to validate the TLS connection. + format: byte + type: string + caProvider: + description: The provider for the CA bundle to use to validate Vault server certificate. + properties: + key: + description: The key where the CA certificate can be found in the Secret or ConfigMap. + type: string + name: + description: The name of the object located at the provider type. + type: string + namespace: + description: |- + The namespace the Provider type is in. + Can only be defined when used in a ClusterSecretStore. + type: string + type: + description: The type of provider to use such as "Secret", or "ConfigMap". + enum: + - Secret + - ConfigMap + type: string + required: + - name + - type + type: object + forwardInconsistent: + description: |- + ForwardInconsistent tells Vault to forward read-after-write requests to the Vault + leader instead of simply retrying within a loop. This can increase performance if + the option is enabled serverside. + https://www.vaultproject.io/docs/configuration/replication#allow_forwarding_via_header + type: boolean + headers: + additionalProperties: + type: string + description: Headers to be added in Vault request + type: object + namespace: + description: |- + Name of the vault namespace. Namespaces is a set of features within Vault Enterprise that allows + Vault environments to support Secure Multi-tenancy. e.g: "ns1". + More about namespaces can be found here https://www.vaultproject.io/docs/enterprise/namespaces + type: string + path: + description: |- + Path is the mount path of the Vault KV backend endpoint, e.g: + "secret". The v2 KV secret engine version specific "/data" path suffix + for fetching secrets from Vault is optional and will be appended + if not present in specified path. + type: string + readYourWrites: + description: |- + ReadYourWrites ensures isolated read-after-write semantics by + providing discovered cluster replication states in each request. + More information about eventual consistency in Vault can be found here + https://www.vaultproject.io/docs/enterprise/consistency + type: boolean + server: + description: 'Server is the connection address for the Vault server, e.g: "https://vault.example.com:8200".' + type: string + tls: + description: |- + The configuration used for client side related TLS communication, when the Vault server + requires mutual authentication. Only used if the Server URL is using HTTPS protocol. + This parameter is ignored for plain HTTP protocol connection. + It's worth noting this configuration is different from the "TLS certificates auth method", + which is available under the `auth.cert` section. + properties: + certSecretRef: + description: |- + CertSecretRef is a certificate added to the transport layer + when communicating with the Vault server. + If no key for the Secret is specified, external-secret will default to 'tls.crt'. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + keySecretRef: + description: |- + KeySecretRef to a key in a Secret resource containing client private key + added to the transport layer when communicating with the Vault server. + If no key for the Secret is specified, external-secret will default to 'tls.key'. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + version: + default: v2 + description: |- + Version is the Vault KV secret engine version. This can be either "v1" or + "v2". Version defaults to "v2". + enum: + - v1 + - v2 + type: string + required: + - auth + - server + type: object + webhook: + description: Webhook configures this store to sync secrets using a generic templated webhook + properties: + body: + description: Body + type: string + caBundle: + description: |- + PEM encoded CA bundle used to validate webhook server certificate. Only used + if the Server URL is using HTTPS protocol. This parameter is ignored for + plain HTTP protocol connection. If not set the system root certificates + are used to validate the TLS connection. + format: byte + type: string + caProvider: + description: The provider for the CA bundle to use to validate webhook server certificate. + properties: + key: + description: The key the value inside of the provider type to use, only used with "Secret" type + type: string + name: + description: The name of the object located at the provider type. + type: string + namespace: + description: The namespace the Provider type is in. + type: string + type: + description: The type of provider to use such as "Secret", or "ConfigMap". + enum: + - Secret + - ConfigMap + type: string + required: + - name + - type + type: object + headers: + additionalProperties: + type: string + description: Headers + type: object + method: + description: Webhook Method + type: string + result: + description: Result formatting + properties: + jsonPath: + description: Json path of return value + type: string + type: object + secrets: + description: |- + Secrets to fill in templates + These secrets will be passed to the templating function as key value pairs under the given name + items: + properties: + name: + description: Name of this secret in templates + type: string + secretRef: + description: Secret ref to fill in credentials + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + required: + - name + - secretRef + type: object + type: array + timeout: + description: Timeout + type: string + url: + description: Webhook url to call + type: string + required: + - result + - url + type: object + yandexcertificatemanager: + description: YandexCertificateManager configures this store to sync secrets using Yandex Certificate Manager provider + properties: + apiEndpoint: + description: Yandex.Cloud API endpoint (e.g. 'api.cloud.yandex.net:443') + type: string + auth: + description: Auth defines the information necessary to authenticate against Yandex Certificate Manager + properties: + authorizedKeySecretRef: + description: The authorized key used for authentication + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + caProvider: + description: The provider for the CA bundle to use to validate Yandex.Cloud server certificate. + properties: + certSecretRef: + description: |- + A reference to a specific 'key' within a Secret resource, + In some instances, `key` is a required field. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + required: + - auth + type: object + yandexlockbox: + description: YandexLockbox configures this store to sync secrets using Yandex Lockbox provider + properties: + apiEndpoint: + description: Yandex.Cloud API endpoint (e.g. 'api.cloud.yandex.net:443') + type: string + auth: + description: Auth defines the information necessary to authenticate against Yandex Lockbox + properties: + authorizedKeySecretRef: + description: The authorized key used for authentication + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + caProvider: + description: The provider for the CA bundle to use to validate Yandex.Cloud server certificate. + properties: + certSecretRef: + description: |- + A reference to a specific 'key' within a Secret resource, + In some instances, `key` is a required field. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + required: + - auth + type: object + type: object + refreshInterval: + description: Used to configure store refresh interval in seconds. Empty or 0 will default to the controller config. + type: integer + retrySettings: + description: Used to configure http retries if failed + properties: + maxRetries: + format: int32 + type: integer + retryInterval: + type: string + type: object + required: + - provider + type: object + status: + description: SecretStoreStatus defines the observed state of the SecretStore. + properties: + capabilities: + description: SecretStoreCapabilities defines the possible operations a SecretStore can do. + type: string + conditions: + items: + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + required: + - status + - type + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- if .Values.crds.conversion.enabled }} + conversion: + strategy: Webhook + webhook: + conversionReviewVersions: + - v1 + clientConfig: + service: + name: {{ include "external-secrets.fullname" . }}-webhook + namespace: {{ .Release.Namespace | quote }} + path: /convert +{{- end }} +{{- end }} diff --git a/kubernetes-vault/external-secrets/templates/crds/uuid.yaml b/kubernetes-vault/external-secrets/templates/crds/uuid.yaml new file mode 100644 index 0000000..1e8cb6e --- /dev/null +++ b/kubernetes-vault/external-secrets/templates/crds/uuid.yaml @@ -0,0 +1,72 @@ +{{- if .Values.installCRDs }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + {{- with .Values.crds.annotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- if and .Values.crds.conversion.enabled .Values.webhook.certManager.enabled .Values.webhook.certManager.addInjectorAnnotations }} + cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/{{ include "external-secrets.fullname" . }}-webhook + {{- end }} + controller-gen.kubebuilder.io/version: v0.16.2 + name: uuids.generators.external-secrets.io +spec: + group: generators.external-secrets.io + names: + categories: + - password + kind: UUID + listKind: UUIDList + plural: uuids + shortNames: + - uuids + singular: uuid + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + Password generates a random password based on the + configuration parameters in spec. + You can specify the length, characterset and other attributes. + 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: UUIDSpec controls the behavior of the uuid generator. + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- if .Values.crds.conversion.enabled }} + conversion: + strategy: Webhook + webhook: + conversionReviewVersions: + - v1 + clientConfig: + service: + name: {{ include "external-secrets.fullname" . }}-webhook + namespace: {{ .Release.Namespace | quote }} + path: /convert +{{- end }} +{{- end }} diff --git a/kubernetes-vault/external-secrets/templates/crds/vaultdynamicsecret.yaml b/kubernetes-vault/external-secrets/templates/crds/vaultdynamicsecret.yaml new file mode 100644 index 0000000..6929b9f --- /dev/null +++ b/kubernetes-vault/external-secrets/templates/crds/vaultdynamicsecret.yaml @@ -0,0 +1,707 @@ +{{- if .Values.installCRDs }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + {{- with .Values.crds.annotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- if and .Values.crds.conversion.enabled .Values.webhook.certManager.enabled .Values.webhook.certManager.addInjectorAnnotations }} + cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/{{ include "external-secrets.fullname" . }}-webhook + {{- end }} + controller-gen.kubebuilder.io/version: v0.16.2 + labels: + external-secrets.io/component: controller + name: vaultdynamicsecrets.generators.external-secrets.io +spec: + group: generators.external-secrets.io + names: + categories: + - vaultdynamicsecret + kind: VaultDynamicSecret + listKind: VaultDynamicSecretList + plural: vaultdynamicsecrets + shortNames: + - vaultdynamicsecret + singular: vaultdynamicsecret + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + properties: + controller: + description: |- + Used to select the correct ESO controller (think: ingress.ingressClassName) + The ESO controller is instantiated with a specific controller name and filters VDS based on this property + type: string + method: + description: Vault API method to use (GET/POST/other) + type: string + parameters: + description: Parameters to pass to Vault write (for non-GET methods) + x-kubernetes-preserve-unknown-fields: true + path: + description: Vault path to obtain the dynamic secret from + type: string + provider: + description: Vault provider common spec + properties: + auth: + description: Auth configures how secret-manager authenticates with the Vault server. + properties: + appRole: + description: |- + AppRole authenticates with Vault using the App Role auth mechanism, + with the role and secret stored in a Kubernetes Secret resource. + properties: + path: + default: approle + description: |- + Path where the App Role authentication backend is mounted + in Vault, e.g: "approle" + type: string + roleId: + description: |- + RoleID configured in the App Role authentication backend when setting + up the authentication backend in Vault. + type: string + roleRef: + description: |- + Reference to a key in a Secret that contains the App Role ID used + to authenticate with Vault. + The `key` field must be specified and denotes which entry within the Secret + resource is used as the app role id. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + secretRef: + description: |- + Reference to a key in a Secret that contains the App Role secret used + to authenticate with Vault. + The `key` field must be specified and denotes which entry within the Secret + resource is used as the app role secret. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + required: + - path + - secretRef + type: object + cert: + description: |- + Cert authenticates with TLS Certificates by passing client certificate, private key and ca certificate + Cert authentication method + properties: + clientCert: + description: |- + ClientCert is a certificate to authenticate using the Cert Vault + authentication method + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + secretRef: + description: |- + SecretRef to a key in a Secret resource containing client private key to + authenticate with Vault using the Cert authentication method + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + iam: + description: |- + Iam authenticates with vault by passing a special AWS request signed with AWS IAM credentials + AWS IAM authentication method + properties: + externalID: + description: AWS External ID set on assumed IAM roles + type: string + jwt: + description: Specify a service account with IRSA enabled + properties: + serviceAccountRef: + description: A reference to a ServiceAccount resource. + properties: + audiences: + description: |- + Audience specifies the `aud` claim for the service account token + If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity + then this audiences will be appended to the list + items: + type: string + type: array + name: + description: The name of the ServiceAccount resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + required: + - name + type: object + type: object + path: + description: 'Path where the AWS auth method is enabled in Vault, e.g: "aws"' + type: string + region: + description: AWS region + type: string + role: + description: This is the AWS role to be assumed before talking to vault + type: string + secretRef: + description: Specify credentials in a Secret object + properties: + accessKeyIDSecretRef: + description: The AccessKeyID is used for authentication + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + secretAccessKeySecretRef: + description: The SecretAccessKey is used for authentication + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + sessionTokenSecretRef: + description: |- + The SessionToken used for authentication + This must be defined if AccessKeyID and SecretAccessKey are temporary credentials + see: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + vaultAwsIamServerID: + description: 'X-Vault-AWS-IAM-Server-ID is an additional header used by Vault IAM auth method to mitigate against different types of replay attacks. More details here: https://developer.hashicorp.com/vault/docs/auth/aws' + type: string + vaultRole: + description: Vault Role. In vault, a role describes an identity with a set of permissions, groups, or policies you want to attach a user of the secrets engine + type: string + required: + - vaultRole + type: object + jwt: + description: |- + Jwt authenticates with Vault by passing role and JWT token using the + JWT/OIDC authentication method + properties: + kubernetesServiceAccountToken: + description: |- + Optional ServiceAccountToken specifies the Kubernetes service account for which to request + a token for with the `TokenRequest` API. + properties: + audiences: + description: |- + Optional audiences field that will be used to request a temporary Kubernetes service + account token for the service account referenced by `serviceAccountRef`. + Defaults to a single audience `vault` it not specified. + Deprecated: use serviceAccountRef.Audiences instead + items: + type: string + type: array + expirationSeconds: + description: |- + Optional expiration time in seconds that will be used to request a temporary + Kubernetes service account token for the service account referenced by + `serviceAccountRef`. + Deprecated: this will be removed in the future. + Defaults to 10 minutes. + format: int64 + type: integer + serviceAccountRef: + description: Service account field containing the name of a kubernetes ServiceAccount. + properties: + audiences: + description: |- + Audience specifies the `aud` claim for the service account token + If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity + then this audiences will be appended to the list + items: + type: string + type: array + name: + description: The name of the ServiceAccount resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + required: + - name + type: object + required: + - serviceAccountRef + type: object + path: + default: jwt + description: |- + Path where the JWT authentication backend is mounted + in Vault, e.g: "jwt" + type: string + role: + description: |- + Role is a JWT role to authenticate using the JWT/OIDC Vault + authentication method + type: string + secretRef: + description: |- + Optional SecretRef that refers to a key in a Secret resource containing JWT token to + authenticate with Vault using the JWT/OIDC authentication method. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + required: + - path + type: object + kubernetes: + description: |- + Kubernetes authenticates with Vault by passing the ServiceAccount + token stored in the named Secret resource to the Vault server. + properties: + mountPath: + default: kubernetes + description: |- + Path where the Kubernetes authentication backend is mounted in Vault, e.g: + "kubernetes" + type: string + role: + description: |- + A required field containing the Vault Role to assume. A Role binds a + Kubernetes ServiceAccount with a set of Vault policies. + type: string + secretRef: + description: |- + Optional secret field containing a Kubernetes ServiceAccount JWT used + for authenticating with Vault. If a name is specified without a key, + `token` is the default. If one is not specified, the one bound to + the controller will be used. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + serviceAccountRef: + description: |- + Optional service account field containing the name of a kubernetes ServiceAccount. + If the service account is specified, the service account secret token JWT will be used + for authenticating with Vault. If the service account selector is not supplied, + the secretRef will be used instead. + properties: + audiences: + description: |- + Audience specifies the `aud` claim for the service account token + If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity + then this audiences will be appended to the list + items: + type: string + type: array + name: + description: The name of the ServiceAccount resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + required: + - name + type: object + required: + - mountPath + - role + type: object + ldap: + description: |- + Ldap authenticates with Vault by passing username/password pair using + the LDAP authentication method + properties: + path: + default: ldap + description: |- + Path where the LDAP authentication backend is mounted + in Vault, e.g: "ldap" + type: string + secretRef: + description: |- + SecretRef to a key in a Secret resource containing password for the LDAP + user used to authenticate with Vault using the LDAP authentication + method + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + username: + description: |- + Username is a LDAP user name used to authenticate using the LDAP Vault + authentication method + type: string + required: + - path + - username + type: object + namespace: + description: |- + Name of the vault namespace to authenticate to. This can be different than the namespace your secret is in. + Namespaces is a set of features within Vault Enterprise that allows + Vault environments to support Secure Multi-tenancy. e.g: "ns1". + More about namespaces can be found here https://www.vaultproject.io/docs/enterprise/namespaces + This will default to Vault.Namespace field if set, or empty otherwise + type: string + tokenSecretRef: + description: TokenSecretRef authenticates with Vault by presenting a token. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + userPass: + description: UserPass authenticates with Vault by passing username/password pair + properties: + path: + default: user + description: |- + Path where the UserPassword authentication backend is mounted + in Vault, e.g: "user" + type: string + secretRef: + description: |- + SecretRef to a key in a Secret resource containing password for the + user used to authenticate with Vault using the UserPass authentication + method + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + username: + description: |- + Username is a user name used to authenticate using the UserPass Vault + authentication method + type: string + required: + - path + - username + type: object + type: object + caBundle: + description: |- + PEM encoded CA bundle used to validate Vault server certificate. Only used + if the Server URL is using HTTPS protocol. This parameter is ignored for + plain HTTP protocol connection. If not set the system root certificates + are used to validate the TLS connection. + format: byte + type: string + caProvider: + description: The provider for the CA bundle to use to validate Vault server certificate. + properties: + key: + description: The key where the CA certificate can be found in the Secret or ConfigMap. + type: string + name: + description: The name of the object located at the provider type. + type: string + namespace: + description: |- + The namespace the Provider type is in. + Can only be defined when used in a ClusterSecretStore. + type: string + type: + description: The type of provider to use such as "Secret", or "ConfigMap". + enum: + - Secret + - ConfigMap + type: string + required: + - name + - type + type: object + forwardInconsistent: + description: |- + ForwardInconsistent tells Vault to forward read-after-write requests to the Vault + leader instead of simply retrying within a loop. This can increase performance if + the option is enabled serverside. + https://www.vaultproject.io/docs/configuration/replication#allow_forwarding_via_header + type: boolean + headers: + additionalProperties: + type: string + description: Headers to be added in Vault request + type: object + namespace: + description: |- + Name of the vault namespace. Namespaces is a set of features within Vault Enterprise that allows + Vault environments to support Secure Multi-tenancy. e.g: "ns1". + More about namespaces can be found here https://www.vaultproject.io/docs/enterprise/namespaces + type: string + path: + description: |- + Path is the mount path of the Vault KV backend endpoint, e.g: + "secret". The v2 KV secret engine version specific "/data" path suffix + for fetching secrets from Vault is optional and will be appended + if not present in specified path. + type: string + readYourWrites: + description: |- + ReadYourWrites ensures isolated read-after-write semantics by + providing discovered cluster replication states in each request. + More information about eventual consistency in Vault can be found here + https://www.vaultproject.io/docs/enterprise/consistency + type: boolean + server: + description: 'Server is the connection address for the Vault server, e.g: "https://vault.example.com:8200".' + type: string + tls: + description: |- + The configuration used for client side related TLS communication, when the Vault server + requires mutual authentication. Only used if the Server URL is using HTTPS protocol. + This parameter is ignored for plain HTTP protocol connection. + It's worth noting this configuration is different from the "TLS certificates auth method", + which is available under the `auth.cert` section. + properties: + certSecretRef: + description: |- + CertSecretRef is a certificate added to the transport layer + when communicating with the Vault server. + If no key for the Secret is specified, external-secret will default to 'tls.crt'. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + keySecretRef: + description: |- + KeySecretRef to a key in a Secret resource containing client private key + added to the transport layer when communicating with the Vault server. + If no key for the Secret is specified, external-secret will default to 'tls.key'. + properties: + key: + description: |- + The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be + defaulted, in others it may be required. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + namespace: + description: |- + Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults + to the namespace of the referent. + type: string + type: object + type: object + version: + default: v2 + description: |- + Version is the Vault KV secret engine version. This can be either "v1" or + "v2". Version defaults to "v2". + enum: + - v1 + - v2 + type: string + required: + - auth + - server + type: object + resultType: + default: Data + description: |- + Result type defines which data is returned from the generator. + By default it is the "data" section of the Vault API response. + When using e.g. /auth/token/create the "data" section is empty but + the "auth" section contains the generated token. + Please refer to the vault docs regarding the result data structure. + enum: + - Data + - Auth + type: string + required: + - path + - provider + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- if .Values.crds.conversion.enabled }} + conversion: + strategy: Webhook + webhook: + conversionReviewVersions: + - v1 + clientConfig: + service: + name: {{ include "external-secrets.fullname" . }}-webhook + namespace: {{ .Release.Namespace | quote }} + path: /convert +{{- end }} +{{- end }} diff --git a/kubernetes-vault/external-secrets/templates/crds/webhook.yaml b/kubernetes-vault/external-secrets/templates/crds/webhook.yaml new file mode 100644 index 0000000..8d38d26 --- /dev/null +++ b/kubernetes-vault/external-secrets/templates/crds/webhook.yaml @@ -0,0 +1,157 @@ +{{- if .Values.installCRDs }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + {{- with .Values.crds.annotations }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- if and .Values.crds.conversion.enabled .Values.webhook.certManager.enabled .Values.webhook.certManager.addInjectorAnnotations }} + cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/{{ include "external-secrets.fullname" . }}-webhook + {{- end }} + controller-gen.kubebuilder.io/version: v0.16.2 + labels: + external-secrets.io/component: controller + name: webhooks.generators.external-secrets.io +spec: + group: generators.external-secrets.io + names: + categories: + - webhook + kind: Webhook + listKind: WebhookList + plural: webhooks + shortNames: + - webhookl + singular: webhook + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + Webhook connects to a third party API server to handle the secrets generation + configuration parameters in spec. + You can specify the server, the token, and additional body parameters. + See documentation for the full API specification for requests and responses. + 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: WebhookSpec controls the behavior of the external generator. Any body parameters should be passed to the server through the parameters field. + properties: + body: + description: Body + type: string + caBundle: + description: |- + PEM encoded CA bundle used to validate webhook server certificate. Only used + if the Server URL is using HTTPS protocol. This parameter is ignored for + plain HTTP protocol connection. If not set the system root certificates + are used to validate the TLS connection. + format: byte + type: string + caProvider: + description: The provider for the CA bundle to use to validate webhook server certificate. + properties: + key: + description: The key the value inside of the provider type to use, only used with "Secret" type + type: string + name: + description: The name of the object located at the provider type. + type: string + namespace: + description: The namespace the Provider type is in. + type: string + type: + description: The type of provider to use such as "Secret", or "ConfigMap". + enum: + - Secret + - ConfigMap + type: string + required: + - name + - type + type: object + headers: + additionalProperties: + type: string + description: Headers + type: object + method: + description: Webhook Method + type: string + result: + description: Result formatting + properties: + jsonPath: + description: Json path of return value + type: string + type: object + secrets: + description: |- + Secrets to fill in templates + These secrets will be passed to the templating function as key value pairs under the given name + items: + properties: + name: + description: Name of this secret in templates + type: string + secretRef: + description: Secret ref to fill in credentials + properties: + key: + description: The key where the token is found. + type: string + name: + description: The name of the Secret resource being referred to. + type: string + type: object + required: + - name + - secretRef + type: object + type: array + timeout: + description: Timeout + type: string + url: + description: Webhook url to call + type: string + required: + - result + - url + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- if .Values.crds.conversion.enabled }} + conversion: + strategy: Webhook + webhook: + conversionReviewVersions: + - v1 + clientConfig: + service: + name: {{ include "external-secrets.fullname" . }}-webhook + namespace: {{ .Release.Namespace | quote }} + path: /convert +{{- end }} +{{- end }} diff --git a/kubernetes-vault/external-secrets/templates/deployment.yaml b/kubernetes-vault/external-secrets/templates/deployment.yaml new file mode 100644 index 0000000..75a908e --- /dev/null +++ b/kubernetes-vault/external-secrets/templates/deployment.yaml @@ -0,0 +1,146 @@ +{{- if .Values.createOperator }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "external-secrets.fullname" . }} + namespace: {{ template "external-secrets.namespace" . }} + labels: + {{- include "external-secrets.labels" . | nindent 4 }} + {{- with .Values.deploymentAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.replicaCount }} + revisionHistoryLimit: {{ .Values.revisionHistoryLimit }} + selector: + matchLabels: + {{- include "external-secrets.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "external-secrets.labels" . | nindent 8 }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "external-secrets.serviceAccountName" . }} + automountServiceAccountToken: {{ .Values.serviceAccount.automount }} + {{- with .Values.podSecurityContext }} + {{- if and (.enabled) (gt (keys . | len) 1) }} + securityContext: + {{- include "external-secrets.renderSecurityContext" (dict "securityContext" . "context" $) | nindent 8 }} + {{- end }} + {{- end }} + hostNetwork: {{ .Values.hostNetwork }} + containers: + - name: {{ .Chart.Name }} + {{- with .Values.securityContext }} + {{- if and (.enabled) (gt (keys . | len) 1) }} + securityContext: + {{- include "external-secrets.renderSecurityContext" (dict "securityContext" . "context" $) | nindent 12 }} + {{- end }} + {{- end }} + image: {{ include "external-secrets.image" (dict "chartAppVersion" .Chart.AppVersion "image" .Values.image) | trim }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- if or (.Values.leaderElect) (.Values.scopedNamespace) (.Values.processClusterStore) (.Values.processClusterExternalSecret) (.Values.concurrent) (.Values.extraArgs) }} + args: + {{- if .Values.leaderElect }} + - --enable-leader-election=true + {{- end }} + {{- if .Values.scopedNamespace }} + - --namespace={{ .Values.scopedNamespace }} + {{- end }} + {{- if and .Values.scopedNamespace .Values.scopedRBAC }} + - --enable-cluster-store-reconciler=false + - --enable-cluster-external-secret-reconciler=false + {{- else }} + {{- if not .Values.processClusterStore }} + - --enable-cluster-store-reconciler=false + {{- end }} + {{- if not .Values.processClusterExternalSecret }} + - --enable-cluster-external-secret-reconciler=false + {{- end }} + {{- end }} + {{- if not .Values.processPushSecret }} + - --enable-push-secret-reconciler=false + {{- end }} + {{- if .Values.controllerClass }} + - --controller-class={{ .Values.controllerClass }} + {{- end }} + {{- if .Values.extendedMetricLabels }} + - --enable-extended-metric-labels={{ .Values.extendedMetricLabels }} + {{- end }} + {{- if .Values.concurrent }} + - --concurrent={{ .Values.concurrent }} + {{- end }} + {{- range $key, $value := .Values.extraArgs }} + {{- if $value }} + - --{{ $key }}={{ $value }} + {{- else }} + - --{{ $key }} + {{- end }} + {{- end }} + {{- end }} + - --metrics-addr=:{{ .Values.metrics.listen.port }} + - --loglevel={{ .Values.log.level }} + - --zap-time-encoding={{ .Values.log.timeEncoding }} + ports: + - containerPort: {{ .Values.metrics.listen.port }} + protocol: TCP + name: metrics + {{- with .Values.extraEnv }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.extraVolumeMounts }} + volumeMounts: + {{- toYaml .Values.extraVolumeMounts | nindent 12 }} + {{- end }} + {{- if .Values.extraContainers }} + {{ toYaml .Values.extraContainers | nindent 8}} + {{- end }} + dnsPolicy: {{ .Values.dnsPolicy }} + {{- if .Values.dnsConfig }} + dnsConfig: + {{- toYaml .Values.dnsConfig | nindent 8 }} + {{- end }} + {{- if .Values.extraVolumes }} + volumes: + {{- toYaml .Values.extraVolumes | nindent 8 }} + {{- end }} + {{- with .Values.nodeSelector | default .Values.global.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity | default .Values.global.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations | default .Values.global.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.topologySpreadConstraints | default .Values.global.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName }} + {{- end }} + {{- if .Values.podSpecExtra }} + {{- toYaml .Values.podSpecExtra | nindent 6 }} + {{- end }} +{{- end }} diff --git a/kubernetes-vault/external-secrets/templates/extra-manifests.yaml b/kubernetes-vault/external-secrets/templates/extra-manifests.yaml new file mode 100644 index 0000000..1dfe8f4 --- /dev/null +++ b/kubernetes-vault/external-secrets/templates/extra-manifests.yaml @@ -0,0 +1,4 @@ +{{- range .Values.extraObjects }} +--- +{{ include "external-secrets.render" (dict "value" . "context" $) }} +{{- end }} diff --git a/kubernetes-vault/external-secrets/templates/poddisruptionbudget.yaml b/kubernetes-vault/external-secrets/templates/poddisruptionbudget.yaml new file mode 100644 index 0000000..7b75ca3 --- /dev/null +++ b/kubernetes-vault/external-secrets/templates/poddisruptionbudget.yaml @@ -0,0 +1,19 @@ +{{- if .Values.podDisruptionBudget.enabled }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "external-secrets.fullname" . }}-pdb + namespace: {{ template "external-secrets.namespace" . }} + labels: + {{- include "external-secrets.labels" . | nindent 4 }} +spec: + {{- if .Values.podDisruptionBudget.minAvailable }} + minAvailable: {{ .Values.podDisruptionBudget.minAvailable }} + {{- end }} + {{- if .Values.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ .Values.podDisruptionBudget.maxUnavailable }} + {{- end }} + selector: + matchLabels: + {{- include "external-secrets.selectorLabels" . | nindent 6 }} +{{- end }} diff --git a/kubernetes-vault/external-secrets/templates/rbac.yaml b/kubernetes-vault/external-secrets/templates/rbac.yaml new file mode 100644 index 0000000..4f4ab48 --- /dev/null +++ b/kubernetes-vault/external-secrets/templates/rbac.yaml @@ -0,0 +1,301 @@ +{{- if .Values.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +{{- if and .Values.scopedNamespace .Values.scopedRBAC }} +kind: Role +{{- else }} +kind: ClusterRole +{{- end }} +metadata: + name: {{ include "external-secrets.fullname" . }}-controller + {{- if and .Values.scopedNamespace .Values.scopedRBAC }} + namespace: {{ .Values.scopedNamespace | quote }} + {{- end }} + labels: + {{- include "external-secrets.labels" . | nindent 4 }} +rules: + - apiGroups: + - "external-secrets.io" + resources: + - "secretstores" + - "clustersecretstores" + - "externalsecrets" + - "clusterexternalsecrets" + - "pushsecrets" + verbs: + - "get" + - "list" + - "watch" + - apiGroups: + - "external-secrets.io" + resources: + - "externalsecrets" + - "externalsecrets/status" + - "externalsecrets/finalizers" + - "secretstores" + - "secretstores/status" + - "secretstores/finalizers" + - "clustersecretstores" + - "clustersecretstores/status" + - "clustersecretstores/finalizers" + - "clusterexternalsecrets" + - "clusterexternalsecrets/status" + - "clusterexternalsecrets/finalizers" + - "pushsecrets" + - "pushsecrets/status" + - "pushsecrets/finalizers" + verbs: + - "get" + - "update" + - "patch" + - apiGroups: + - "generators.external-secrets.io" + resources: + - "acraccesstokens" + - "ecrauthorizationtokens" + - "fakes" + - "gcraccesstokens" + - "githubaccesstokens" + - "passwords" + - "vaultdynamicsecrets" + - "webhooks" + verbs: + - "get" + - "list" + - "watch" + - apiGroups: + - "" + resources: + - "serviceaccounts" + - "namespaces" + verbs: + - "get" + - "list" + - "watch" + - apiGroups: + - "" + resources: + - "configmaps" + verbs: + - "get" + - "list" + - "watch" + - apiGroups: + - "" + resources: + - "secrets" + verbs: + - "get" + - "list" + - "watch" + - "create" + - "update" + - "delete" + - "patch" + - apiGroups: + - "" + resources: + - "serviceaccounts/token" + verbs: + - "create" + - apiGroups: + - "" + resources: + - "events" + verbs: + - "create" + - "patch" + - apiGroups: + - "external-secrets.io" + resources: + - "externalsecrets" + verbs: + - "create" + - "update" + - "delete" +--- +apiVersion: rbac.authorization.k8s.io/v1 +{{- if and .Values.scopedNamespace .Values.scopedRBAC }} +kind: Role +{{- else }} +kind: ClusterRole +{{- end }} +metadata: + name: {{ include "external-secrets.fullname" . }}-view + {{- if and .Values.scopedNamespace .Values.scopedRBAC }} + namespace: {{ .Values.scopedNamespace | quote }} + {{- end }} + labels: + {{- include "external-secrets.labels" . | nindent 4 }} + rbac.authorization.k8s.io/aggregate-to-view: "true" + rbac.authorization.k8s.io/aggregate-to-edit: "true" + rbac.authorization.k8s.io/aggregate-to-admin: "true" +rules: + - apiGroups: + - "external-secrets.io" + resources: + - "externalsecrets" + - "secretstores" + - "clustersecretstores" + - "pushsecrets" + verbs: + - "get" + - "watch" + - "list" + - apiGroups: + - "generators.external-secrets.io" + resources: + - "acraccesstokens" + - "ecrauthorizationtokens" + - "fakes" + - "gcraccesstokens" + - "githubaccesstokens" + - "passwords" + - "vaultdynamicsecrets" + - "webhooks" + verbs: + - "get" + - "watch" + - "list" +--- +apiVersion: rbac.authorization.k8s.io/v1 +{{- if and .Values.scopedNamespace .Values.scopedRBAC }} +kind: Role +{{- else }} +kind: ClusterRole +{{- end }} +metadata: + name: {{ include "external-secrets.fullname" . }}-edit + {{- if and .Values.scopedNamespace .Values.scopedRBAC }} + namespace: {{ .Values.scopedNamespace | quote }} + {{- end }} + labels: + {{- include "external-secrets.labels" . | nindent 4 }} + rbac.authorization.k8s.io/aggregate-to-edit: "true" + rbac.authorization.k8s.io/aggregate-to-admin: "true" +rules: + - apiGroups: + - "external-secrets.io" + resources: + - "externalsecrets" + - "secretstores" + - "clustersecretstores" + - "pushsecrets" + verbs: + - "create" + - "delete" + - "deletecollection" + - "patch" + - "update" + - apiGroups: + - "generators.external-secrets.io" + resources: + - "acraccesstokens" + - "ecrauthorizationtokens" + - "fakes" + - "gcraccesstokens" + - "githubaccesstokens" + - "passwords" + - "vaultdynamicsecrets" + - "webhooks" + verbs: + - "create" + - "delete" + - "deletecollection" + - "patch" + - "update" +--- +apiVersion: rbac.authorization.k8s.io/v1 +{{- if and .Values.scopedNamespace .Values.scopedRBAC }} +kind: RoleBinding +{{- else }} +kind: ClusterRoleBinding +{{- end }} +metadata: + name: {{ include "external-secrets.fullname" . }}-controller + {{- if and .Values.scopedNamespace .Values.scopedRBAC }} + namespace: {{ .Values.scopedNamespace | quote }} + {{- end }} + labels: + {{- include "external-secrets.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + {{- if and .Values.scopedNamespace .Values.scopedRBAC }} + kind: Role + {{- else }} + kind: ClusterRole + {{- end }} + name: {{ include "external-secrets.fullname" . }}-controller +subjects: + - name: {{ include "external-secrets.serviceAccountName" . }} + namespace: {{ template "external-secrets.namespace" . }} + kind: ServiceAccount +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ include "external-secrets.fullname" . }}-leaderelection + namespace: {{ template "external-secrets.namespace" . }} + labels: + {{- include "external-secrets.labels" . | nindent 4 }} +rules: + - apiGroups: + - "" + resources: + - "configmaps" + resourceNames: + - "external-secrets-controller" + verbs: + - "get" + - "update" + - "patch" + - apiGroups: + - "" + resources: + - "configmaps" + verbs: + - "create" + - apiGroups: + - "coordination.k8s.io" + resources: + - "leases" + verbs: + - "get" + - "create" + - "update" + - "patch" +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "external-secrets.fullname" . }}-leaderelection + namespace: {{ template "external-secrets.namespace" . }} + labels: + {{- include "external-secrets.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ include "external-secrets.fullname" . }}-leaderelection +subjects: + - kind: ServiceAccount + name: {{ include "external-secrets.serviceAccountName" . }} + namespace: {{ template "external-secrets.namespace" . }} +{{- if .Values.rbac.servicebindings.create }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "external-secrets.fullname" . }}-servicebindings + labels: + servicebinding.io/controller: "true" + {{- include "external-secrets.labels" . | nindent 4 }} +rules: + - apiGroups: + - "external-secrets.io" + resources: + - "externalsecrets" + verbs: + - "get" + - "list" + - "watch" +{{- end }} +{{- end }} diff --git a/kubernetes-vault/external-secrets/templates/service.yaml b/kubernetes-vault/external-secrets/templates/service.yaml new file mode 100644 index 0000000..94859a3 --- /dev/null +++ b/kubernetes-vault/external-secrets/templates/service.yaml @@ -0,0 +1,28 @@ +{{- if .Values.metrics.service.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "external-secrets.fullname" . }}-metrics + namespace: {{ template "external-secrets.namespace" . }} + labels: + {{- include "external-secrets.labels" . | nindent 4 }} + {{- with .Values.metrics.service.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + type: ClusterIP + {{- if .Values.service.ipFamilyPolicy }} + ipFamilyPolicy: {{ .Values.service.ipFamilyPolicy }} + {{- end }} + {{- if .Values.service.ipFamilies }} + ipFamilies: {{ .Values.service.ipFamilies | toYaml | nindent 2 }} + {{- end }} + ports: + - port: {{ .Values.metrics.service.port }} + protocol: TCP + targetPort: metrics + name: metrics + selector: + {{- include "external-secrets.selectorLabels" . | nindent 4 }} +{{- end }} diff --git a/kubernetes-vault/external-secrets/templates/serviceaccount.yaml b/kubernetes-vault/external-secrets/templates/serviceaccount.yaml new file mode 100644 index 0000000..ceaa98e --- /dev/null +++ b/kubernetes-vault/external-secrets/templates/serviceaccount.yaml @@ -0,0 +1,16 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "external-secrets.serviceAccountName" . }} + namespace: {{ template "external-secrets.namespace" . }} + labels: + {{- include "external-secrets.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.extraLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/kubernetes-vault/external-secrets/templates/servicemonitor.yaml b/kubernetes-vault/external-secrets/templates/servicemonitor.yaml new file mode 100644 index 0000000..3145179 --- /dev/null +++ b/kubernetes-vault/external-secrets/templates/servicemonitor.yaml @@ -0,0 +1,164 @@ +{{- if and ( .Capabilities.APIVersions.Has "monitoring.coreos.com/v1" ) .Values.serviceMonitor.enabled -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "external-secrets.fullname" . }}-metrics + namespace: {{ template "external-secrets.namespace" . }} + labels: + {{- include "external-secrets.labels" . | nindent 4 }} +spec: + type: ClusterIP + {{- if .Values.service.ipFamilyPolicy }} + ipFamilyPolicy: {{ .Values.service.ipFamilyPolicy }} + {{- end }} + {{- if .Values.service.ipFamilies }} + ipFamilies: {{ .Values.service.ipFamilies | toYaml | nindent 2 }} + {{- end }} + ports: + - port: {{ .Values.metrics.service.port }} + protocol: TCP + name: metrics + selector: + {{- include "external-secrets.selectorLabels" . | nindent 4 }} +--- +apiVersion: "monitoring.coreos.com/v1" +kind: ServiceMonitor +metadata: + labels: + {{- include "external-secrets.labels" . | nindent 4 }} +{{- if .Values.serviceMonitor.additionalLabels }} +{{ toYaml .Values.serviceMonitor.additionalLabels | indent 4 }} +{{- end }} + name: {{ include "external-secrets.fullname" . }}-metrics + namespace: {{ .Values.serviceMonitor.namespace | default (include "external-secrets.namespace" .) | quote }} +spec: + selector: + matchLabels: + {{- include "external-secrets.selectorLabels" . | nindent 6 }} + namespaceSelector: + matchNames: + - {{ template "external-secrets.namespace" . }} + endpoints: + - port: metrics + interval: {{ .Values.serviceMonitor.interval }} + scrapeTimeout: {{ .Values.serviceMonitor.scrapeTimeout }} + honorLabels: {{ .Values.serviceMonitor.honorLabels }} + {{- with .Values.serviceMonitor.metricRelabelings }} + metricRelabelings: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.serviceMonitor.relabelings }} + relabelings: + {{- toYaml . | nindent 6 }} + {{- end }} +--- +{{- if .Values.webhook.create }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "external-secrets.fullname" . }}-webhook-metrics + namespace: {{ template "external-secrets.namespace" . }} + labels: + {{- include "external-secrets-webhook-metrics.labels" . | nindent 4 }} +spec: + type: ClusterIP + {{- if .Values.service.ipFamilyPolicy }} + ipFamilyPolicy: {{ .Values.service.ipFamilyPolicy }} + {{- end }} + {{- if .Values.service.ipFamilies }} + ipFamilies: {{ .Values.service.ipFamilies | toYaml | nindent 2 }} + {{- end }} + ports: + - port: {{ .Values.webhook.metrics.service.port }} + protocol: TCP + name: metrics + selector: + {{- include "external-secrets-webhook.selectorLabels" . | nindent 4 }} +--- +apiVersion: "monitoring.coreos.com/v1" +kind: ServiceMonitor +metadata: + labels: + {{- include "external-secrets-webhook.labels" . | nindent 4 }} +{{- if .Values.serviceMonitor.additionalLabels }} +{{ toYaml .Values.serviceMonitor.additionalLabels | indent 4 }} +{{- end }} + name: {{ include "external-secrets.fullname" . }}-webhook-metrics + namespace: {{ .Values.serviceMonitor.namespace | default (include "external-secrets.namespace" .) | quote }} +spec: + selector: + matchLabels: + {{- include "external-secrets-webhook-metrics.labels" . | nindent 6 }} + namespaceSelector: + matchNames: + - {{ template "external-secrets.namespace" . }} + endpoints: + - port: metrics + interval: {{ .Values.serviceMonitor.interval }} + scrapeTimeout: {{ .Values.serviceMonitor.scrapeTimeout }} + honorLabels: {{ .Values.serviceMonitor.honorLabels }} + {{- with .Values.serviceMonitor.metricRelabelings }} + metricRelabelings: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.serviceMonitor.relabelings }} + relabelings: + {{- toYaml . | nindent 6 }} + {{- end }} +{{- end }} +--- +{{- if .Values.certController.create }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "external-secrets.fullname" . }}-cert-controller-metrics + namespace: {{ template "external-secrets.namespace" . }} + labels: + {{- include "external-secrets-cert-controller-metrics.labels" . | nindent 4 }} +spec: + type: ClusterIP + {{- if .Values.service.ipFamilyPolicy }} + ipFamilyPolicy: {{ .Values.service.ipFamilyPolicy }} + {{- end }} + {{- if .Values.service.ipFamilies }} + ipFamilies: {{ .Values.service.ipFamilies | toYaml | nindent 2 }} + {{- end }} + ports: + - port: {{ .Values.certController.metrics.listen.port }} + protocol: TCP + name: metrics + selector: + {{- include "external-secrets-cert-controller.selectorLabels" . | nindent 4 }} +--- +apiVersion: "monitoring.coreos.com/v1" +kind: ServiceMonitor +metadata: + labels: + {{- include "external-secrets-cert-controller.labels" . | nindent 4 }} +{{- if .Values.serviceMonitor.additionalLabels }} +{{ toYaml .Values.serviceMonitor.additionalLabels | indent 4 }} +{{- end }} + name: {{ include "external-secrets.fullname" . }}-cert-controller-metrics + namespace: {{ .Values.serviceMonitor.namespace | default (include "external-secrets.namespace" .) | quote }} +spec: + selector: + matchLabels: + {{- include "external-secrets-cert-controller-metrics.labels" . | nindent 6 }} + namespaceSelector: + matchNames: + - {{ template "external-secrets.namespace" . }} + endpoints: + - port: metrics + interval: {{ .Values.serviceMonitor.interval }} + scrapeTimeout: {{ .Values.serviceMonitor.scrapeTimeout }} + honorLabels: {{ .Values.serviceMonitor.honorLabels }} + {{- with .Values.serviceMonitor.metricRelabelings }} + metricRelabelings: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.serviceMonitor.relabelings }} + relabelings: + {{- toYaml . | nindent 6 }} + {{- end }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/external-secrets/templates/validatingwebhook.yaml b/kubernetes-vault/external-secrets/templates/validatingwebhook.yaml new file mode 100644 index 0000000..63b3976 --- /dev/null +++ b/kubernetes-vault/external-secrets/templates/validatingwebhook.yaml @@ -0,0 +1,78 @@ +{{- if .Values.webhook.create }} +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: secretstore-validate + labels: + external-secrets.io/component: webhook + {{- with .Values.commonLabels }} + {{ toYaml . | nindent 4 }} + {{- end }} + {{- if and .Values.webhook.certManager.enabled .Values.webhook.certManager.addInjectorAnnotations }} + annotations: + cert-manager.io/inject-ca-from: {{ template "external-secrets.namespace" . }}/{{ include "external-secrets.fullname" . }}-webhook + {{- end }} +webhooks: +- name: "validate.secretstore.external-secrets.io" + rules: + - apiGroups: ["external-secrets.io"] + apiVersions: ["v1beta1"] + operations: ["CREATE", "UPDATE", "DELETE"] + resources: ["secretstores"] + scope: "Namespaced" + clientConfig: + service: + namespace: {{ template "external-secrets.namespace" . }} + name: {{ include "external-secrets.fullname" . }}-webhook + path: /validate-external-secrets-io-v1beta1-secretstore + admissionReviewVersions: ["v1", "v1beta1"] + sideEffects: None + timeoutSeconds: 5 + +- name: "validate.clustersecretstore.external-secrets.io" + rules: + - apiGroups: ["external-secrets.io"] + apiVersions: ["v1beta1"] + operations: ["CREATE", "UPDATE", "DELETE"] + resources: ["clustersecretstores"] + scope: "Cluster" + clientConfig: + service: + namespace: {{ template "external-secrets.namespace" . }} + name: {{ include "external-secrets.fullname" . }}-webhook + path: /validate-external-secrets-io-v1beta1-clustersecretstore + admissionReviewVersions: ["v1", "v1beta1"] + sideEffects: None + timeoutSeconds: 5 +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: externalsecret-validate + labels: + external-secrets.io/component: webhook + {{- with .Values.commonLabels }} + {{ toYaml . | nindent 4 }} + {{- end }} + {{- if and .Values.webhook.certManager.enabled .Values.webhook.certManager.addInjectorAnnotations }} + annotations: + cert-manager.io/inject-ca-from: {{ template "external-secrets.namespace" . }}/{{ include "external-secrets.fullname" . }}-webhook + {{- end }} +webhooks: +- name: "validate.externalsecret.external-secrets.io" + rules: + - apiGroups: ["external-secrets.io"] + apiVersions: ["v1beta1"] + operations: ["CREATE", "UPDATE", "DELETE"] + resources: ["externalsecrets"] + scope: "Namespaced" + clientConfig: + service: + namespace: {{ template "external-secrets.namespace" . }} + name: {{ include "external-secrets.fullname" . }}-webhook + path: /validate-external-secrets-io-v1beta1-externalsecret + admissionReviewVersions: ["v1", "v1beta1"] + sideEffects: None + timeoutSeconds: 5 + failurePolicy: {{ .Values.webhook.failurePolicy}} +{{- end }} diff --git a/kubernetes-vault/external-secrets/templates/webhook-certificate.yaml b/kubernetes-vault/external-secrets/templates/webhook-certificate.yaml new file mode 100644 index 0000000..adb19fd --- /dev/null +++ b/kubernetes-vault/external-secrets/templates/webhook-certificate.yaml @@ -0,0 +1,30 @@ +{{- if and .Values.webhook.create .Values.webhook.certManager.enabled .Values.webhook.certManager.cert.create }} +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: {{ include "external-secrets.fullname" . }}-webhook + namespace: {{ template "external-secrets.namespace" . }} + labels: + {{- include "external-secrets-webhook.labels" . | nindent 4 }} + external-secrets.io/component: webhook + {{- with .Values.webhook.certManager.cert.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + commonName: {{ include "external-secrets.fullname" . }}-webhook + dnsNames: + - {{ include "external-secrets.fullname" . }}-webhook + - {{ include "external-secrets.fullname" . }}-webhook.{{ template "external-secrets.namespace" . }} + - {{ include "external-secrets.fullname" . }}-webhook.{{ template "external-secrets.namespace" . }}.svc + issuerRef: + {{- toYaml .Values.webhook.certManager.cert.issuerRef | nindent 4 }} + {{- with .Values.webhook.certManager.cert.duration }} + duration: {{ . | quote }} + {{- end }} + {{- with .Values.webhook.certManager.cert.renewBefore }} + renewBefore: {{ . | quote }} + {{- end }} + secretName: {{ include "external-secrets.fullname" . }}-webhook +{{- end }} diff --git a/kubernetes-vault/external-secrets/templates/webhook-deployment.yaml b/kubernetes-vault/external-secrets/templates/webhook-deployment.yaml new file mode 100644 index 0000000..7419a42 --- /dev/null +++ b/kubernetes-vault/external-secrets/templates/webhook-deployment.yaml @@ -0,0 +1,128 @@ +{{- if .Values.webhook.create }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "external-secrets.fullname" . }}-webhook + namespace: {{ template "external-secrets.namespace" . }} + labels: + {{- include "external-secrets-webhook.labels" . | nindent 4 }} + {{- with .Values.webhook.deploymentAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.webhook.replicaCount }} + revisionHistoryLimit: {{ .Values.webhook.revisionHistoryLimit }} + selector: + matchLabels: + {{- include "external-secrets-webhook.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.webhook.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "external-secrets-webhook.labels" . | nindent 8 }} + {{- with .Values.webhook.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.webhook.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + hostNetwork: {{ .Values.webhook.hostNetwork}} + serviceAccountName: {{ include "external-secrets-webhook.serviceAccountName" . }} + automountServiceAccountToken: {{ .Values.webhook.serviceAccount.automount }} + {{- with .Values.webhook.podSecurityContext }} + {{- if and (.enabled) (gt (keys . | len) 1) }} + securityContext: + {{- include "external-secrets.renderSecurityContext" (dict "securityContext" . "context" $) | nindent 8 }} + {{- end }} + {{- end }} + containers: + - name: webhook + {{- with .Values.webhook.securityContext }} + {{- if and (.enabled) (gt (keys . | len) 1) }} + securityContext: + {{- include "external-secrets.renderSecurityContext" (dict "securityContext" . "context" $) | nindent 12 }} + {{- end }} + {{- end }} + image: {{ include "external-secrets.image" (dict "chartAppVersion" .Chart.AppVersion "image" .Values.webhook.image) | trim }} + imagePullPolicy: {{ .Values.webhook.image.pullPolicy }} + args: + - webhook + - --port={{ .Values.webhook.port }} + - --dns-name={{ include "external-secrets.fullname" . }}-webhook.{{ template "external-secrets.namespace" . }}.svc + - --cert-dir={{ .Values.webhook.certDir }} + - --check-interval={{ .Values.webhook.certCheckInterval }} + - --metrics-addr=:{{ .Values.webhook.metrics.listen.port }} + - --healthz-addr={{ .Values.webhook.readinessProbe.address }}:{{ .Values.webhook.readinessProbe.port }} + - --loglevel={{ .Values.webhook.log.level }} + - --zap-time-encoding={{ .Values.webhook.log.timeEncoding }} + {{- if .Values.webhook.lookaheadInterval }} + - --lookahead-interval={{ .Values.webhook.lookaheadInterval }} + {{- end }} + {{- range $key, $value := .Values.webhook.extraArgs }} + {{- if $value }} + - --{{ $key }}={{ $value }} + {{- else }} + - --{{ $key }} + {{- end }} + {{- end }} + ports: + - containerPort: {{ .Values.webhook.metrics.listen.port }} + protocol: TCP + name: metrics + - containerPort: {{ .Values.webhook.port }} + protocol: TCP + name: webhook + readinessProbe: + httpGet: + port: {{ .Values.webhook.readinessProbe.port }} + path: /readyz + initialDelaySeconds: 20 + periodSeconds: 5 + {{- with .Values.webhook.extraEnv }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.webhook.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + - name: certs + mountPath: {{ .Values.webhook.certDir }} + readOnly: true + {{- if .Values.webhook.extraVolumeMounts }} + {{- toYaml .Values.webhook.extraVolumeMounts | nindent 12 }} + {{- end }} + volumes: + - name: certs + secret: + secretName: {{ include "external-secrets.fullname" . }}-webhook + {{- if .Values.webhook.extraVolumes }} + {{- toYaml .Values.webhook.extraVolumes | nindent 8 }} + {{- end }} + {{- with .Values.webhook.nodeSelector | default .Values.global.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.webhook.affinity | default .Values.global.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.webhook.tolerations | default .Values.global.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.webhook.topologySpreadConstraints | default .Values.global.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.webhook.priorityClassName }} + priorityClassName: {{ .Values.webhook.priorityClassName }} + {{- end }} +{{- end }} diff --git a/kubernetes-vault/external-secrets/templates/webhook-poddisruptionbudget.yaml b/kubernetes-vault/external-secrets/templates/webhook-poddisruptionbudget.yaml new file mode 100644 index 0000000..58345ba --- /dev/null +++ b/kubernetes-vault/external-secrets/templates/webhook-poddisruptionbudget.yaml @@ -0,0 +1,20 @@ +{{- if and .Values.webhook.create .Values.webhook.podDisruptionBudget.enabled }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "external-secrets.fullname" . }}-webhook-pdb + namespace: {{ template "external-secrets.namespace" . }} + labels: + {{- include "external-secrets-webhook.labels" . | nindent 4 }} + external-secrets.io/component: webhook +spec: + {{- if .Values.webhook.podDisruptionBudget.minAvailable }} + minAvailable: {{ .Values.webhook.podDisruptionBudget.minAvailable }} + {{- end }} + {{- if .Values.webhook.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ .Values.webhook.podDisruptionBudget.maxUnavailable }} + {{- end }} + selector: + matchLabels: + {{- include "external-secrets-webhook.selectorLabels" . | nindent 6 }} +{{- end }} diff --git a/kubernetes-vault/external-secrets/templates/webhook-secret.yaml b/kubernetes-vault/external-secrets/templates/webhook-secret.yaml new file mode 100644 index 0000000..fa7760e --- /dev/null +++ b/kubernetes-vault/external-secrets/templates/webhook-secret.yaml @@ -0,0 +1,14 @@ +{{- if and .Values.webhook.create (not .Values.webhook.certManager.enabled) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "external-secrets.fullname" . }}-webhook + namespace: {{ template "external-secrets.namespace" . }} + labels: + {{- include "external-secrets-webhook.labels" . | nindent 4 }} + external-secrets.io/component: webhook + {{- with .Values.webhook.secretAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/kubernetes-vault/external-secrets/templates/webhook-service.yaml b/kubernetes-vault/external-secrets/templates/webhook-service.yaml new file mode 100644 index 0000000..59dbddc --- /dev/null +++ b/kubernetes-vault/external-secrets/templates/webhook-service.yaml @@ -0,0 +1,37 @@ +{{- if .Values.webhook.create }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "external-secrets.fullname" . }}-webhook + namespace: {{ template "external-secrets.namespace" . }} + labels: + {{- include "external-secrets-webhook.labels" . | nindent 4 }} + external-secrets.io/component: webhook + {{- if .Values.webhook.metrics.service.enabled }} + {{- with .Values.webhook.metrics.service.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +spec: + type: ClusterIP + {{- if .Values.service.ipFamilyPolicy }} + ipFamilyPolicy: {{ .Values.service.ipFamilyPolicy }} + {{- end }} + {{- if .Values.service.ipFamilies }} + ipFamilies: {{ .Values.service.ipFamilies | toYaml | nindent 2 }} + {{- end }} + ports: + - port: 443 + targetPort: {{ .Values.webhook.port }} + protocol: TCP + name: webhook + {{- if .Values.webhook.metrics.service.enabled }} + - port: {{ .Values.webhook.metrics.service.port }} + protocol: TCP + targetPort: metrics + name: metrics + {{- end }} + selector: + {{- include "external-secrets-webhook.selectorLabels" . | nindent 4 }} +{{- end }} diff --git a/kubernetes-vault/external-secrets/templates/webhook-serviceaccount.yaml b/kubernetes-vault/external-secrets/templates/webhook-serviceaccount.yaml new file mode 100644 index 0000000..1936218 --- /dev/null +++ b/kubernetes-vault/external-secrets/templates/webhook-serviceaccount.yaml @@ -0,0 +1,16 @@ +{{- if and .Values.webhook.create .Values.webhook.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "external-secrets-webhook.serviceAccountName" . }} + namespace: {{ template "external-secrets.namespace" . }} + labels: + {{- include "external-secrets-webhook.labels" . | nindent 4 }} + {{- with .Values.webhook.serviceAccount.extraLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.webhook.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/kubernetes-vault/external-secrets/values.schema.json b/kubernetes-vault/external-secrets/values.schema.json new file mode 100644 index 0000000..08cef96 --- /dev/null +++ b/kubernetes-vault/external-secrets/values.schema.json @@ -0,0 +1,905 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "properties": { + "affinity": { + "properties": {}, + "type": "object" + }, + "bitwarden-sdk-server": { + "properties": { + "enabled": { + "type": "boolean" + } + }, + "type": "object" + }, + "certController": { + "properties": { + "affinity": { + "properties": {}, + "type": "object" + }, + "create": { + "type": "boolean" + }, + "deploymentAnnotations": { + "properties": {}, + "type": "object" + }, + "extraArgs": { + "properties": {}, + "type": "object" + }, + "extraEnv": { + "type": "array" + }, + "extraVolumeMounts": { + "type": "array" + }, + "extraVolumes": { + "type": "array" + }, + "fullnameOverride": { + "type": "string" + }, + "hostNetwork": { + "type": "boolean" + }, + "image": { + "properties": { + "flavour": { + "type": "string" + }, + "pullPolicy": { + "type": "string" + }, + "repository": { + "type": "string" + }, + "tag": { + "type": "string" + } + }, + "type": "object" + }, + "imagePullSecrets": { + "type": "array" + }, + "log": { + "properties": { + "level": { + "type": "string" + }, + "timeEncoding": { + "type": "string" + } + }, + "type": "object" + }, + "metrics": { + "properties": { + "listen": { + "properties": { + "port": { + "type": "integer" + } + }, + "type": "object" + }, + "service": { + "properties": { + "annotations": { + "properties": {}, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "nameOverride": { + "type": "string" + }, + "nodeSelector": { + "properties": {}, + "type": "object" + }, + "podAnnotations": { + "properties": {}, + "type": "object" + }, + "podDisruptionBudget": { + "properties": { + "enabled": { + "type": "boolean" + }, + "minAvailable": { + "type": "integer" + } + }, + "type": "object" + }, + "podLabels": { + "properties": {}, + "type": "object" + }, + "podSecurityContext": { + "properties": { + "enabled": { + "type": "boolean" + } + }, + "type": "object" + }, + "priorityClassName": { + "type": "string" + }, + "rbac": { + "properties": { + "create": { + "type": "boolean" + } + }, + "type": "object" + }, + "readinessProbe": { + "properties": { + "address": { + "type": "string" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + }, + "replicaCount": { + "type": "integer" + }, + "requeueInterval": { + "type": "string" + }, + "resources": { + "properties": {}, + "type": "object" + }, + "revisionHistoryLimit": { + "type": "integer" + }, + "securityContext": { + "properties": { + "allowPrivilegeEscalation": { + "type": "boolean" + }, + "capabilities": { + "properties": { + "drop": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "readOnlyRootFilesystem": { + "type": "boolean" + }, + "runAsNonRoot": { + "type": "boolean" + }, + "runAsUser": { + "type": "integer" + }, + "seccompProfile": { + "properties": { + "type": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "serviceAccount": { + "properties": { + "annotations": { + "properties": {}, + "type": "object" + }, + "automount": { + "type": "boolean" + }, + "create": { + "type": "boolean" + }, + "extraLabels": { + "properties": {}, + "type": "object" + }, + "name": { + "type": "string" + } + }, + "type": "object" + }, + "tolerations": { + "type": "array" + }, + "topologySpreadConstraints": { + "type": "array" + } + }, + "type": "object" + }, + "commonLabels": { + "properties": {}, + "type": "object" + }, + "concurrent": { + "type": "integer" + }, + "controllerClass": { + "type": "string" + }, + "crds": { + "properties": { + "annotations": { + "properties": {}, + "type": "object" + }, + "conversion": { + "properties": { + "enabled": { + "type": "boolean" + } + }, + "type": "object" + }, + "createClusterExternalSecret": { + "type": "boolean" + }, + "createClusterSecretStore": { + "type": "boolean" + }, + "createPushSecret": { + "type": "boolean" + } + }, + "type": "object" + }, + "createOperator": { + "type": "boolean" + }, + "deploymentAnnotations": { + "properties": {}, + "type": "object" + }, + "dnsConfig": { + "properties": {}, + "type": "object" + }, + "dnsPolicy": { + "type": "string" + }, + "extendedMetricLabels": { + "type": "boolean" + }, + "extraArgs": { + "properties": {}, + "type": "object" + }, + "extraContainers": { + "type": "array" + }, + "extraEnv": { + "type": "array" + }, + "extraObjects": { + "type": "array" + }, + "extraVolumeMounts": { + "type": "array" + }, + "extraVolumes": { + "type": "array" + }, + "fullnameOverride": { + "type": "string" + }, + "global": { + "properties": { + "affinity": { + "properties": {}, + "type": "object" + }, + "compatibility": { + "properties": { + "openshift": { + "properties": { + "adaptSecurityContext": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "nodeSelector": { + "properties": {}, + "type": "object" + }, + "tolerations": { + "type": "array" + }, + "topologySpreadConstraints": { + "type": "array" + } + }, + "type": "object" + }, + "hostNetwork": { + "type": "boolean" + }, + "image": { + "properties": { + "flavour": { + "type": "string" + }, + "pullPolicy": { + "type": "string" + }, + "repository": { + "type": "string" + }, + "tag": { + "type": "string" + } + }, + "type": "object" + }, + "imagePullSecrets": { + "type": "array" + }, + "installCRDs": { + "type": "boolean" + }, + "leaderElect": { + "type": "boolean" + }, + "log": { + "properties": { + "level": { + "type": "string" + }, + "timeEncoding": { + "type": "string" + } + }, + "type": "object" + }, + "metrics": { + "properties": { + "listen": { + "properties": { + "port": { + "type": "integer" + } + }, + "type": "object" + }, + "service": { + "properties": { + "annotations": { + "properties": {}, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "nameOverride": { + "type": "string" + }, + "namespaceOverride": { + "type": "string" + }, + "nodeSelector": { + "properties": {}, + "type": "object" + }, + "podAnnotations": { + "properties": {}, + "type": "object" + }, + "podDisruptionBudget": { + "properties": { + "enabled": { + "type": "boolean" + }, + "minAvailable": { + "type": "integer" + } + }, + "type": "object" + }, + "podLabels": { + "properties": {}, + "type": "object" + }, + "podSecurityContext": { + "properties": { + "enabled": { + "type": "boolean" + } + }, + "type": "object" + }, + "podSpecExtra": { + "properties": {}, + "type": "object" + }, + "priorityClassName": { + "type": "string" + }, + "processClusterExternalSecret": { + "type": "boolean" + }, + "processClusterStore": { + "type": "boolean" + }, + "processPushSecret": { + "type": "boolean" + }, + "rbac": { + "properties": { + "create": { + "type": "boolean" + }, + "servicebindings": { + "properties": { + "create": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "replicaCount": { + "type": "integer" + }, + "resources": { + "properties": {}, + "type": "object" + }, + "revisionHistoryLimit": { + "type": "integer" + }, + "scopedNamespace": { + "type": "string" + }, + "scopedRBAC": { + "type": "boolean" + }, + "securityContext": { + "properties": { + "allowPrivilegeEscalation": { + "type": "boolean" + }, + "capabilities": { + "properties": { + "drop": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "readOnlyRootFilesystem": { + "type": "boolean" + }, + "runAsNonRoot": { + "type": "boolean" + }, + "runAsUser": { + "type": "integer" + }, + "seccompProfile": { + "properties": { + "type": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "service": { + "properties": { + "ipFamilies": { + "type": "array" + }, + "ipFamilyPolicy": { + "type": "string" + } + }, + "type": "object" + }, + "serviceAccount": { + "properties": { + "annotations": { + "properties": {}, + "type": "object" + }, + "automount": { + "type": "boolean" + }, + "create": { + "type": "boolean" + }, + "extraLabels": { + "properties": {}, + "type": "object" + }, + "name": { + "type": "string" + } + }, + "type": "object" + }, + "serviceMonitor": { + "properties": { + "additionalLabels": { + "properties": {}, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "honorLabels": { + "type": "boolean" + }, + "interval": { + "type": "string" + }, + "metricRelabelings": { + "type": "array" + }, + "namespace": { + "type": "string" + }, + "relabelings": { + "type": "array" + }, + "scrapeTimeout": { + "type": "string" + } + }, + "type": "object" + }, + "tolerations": { + "type": "array" + }, + "topologySpreadConstraints": { + "type": "array" + }, + "webhook": { + "properties": { + "affinity": { + "properties": {}, + "type": "object" + }, + "certCheckInterval": { + "type": "string" + }, + "certDir": { + "type": "string" + }, + "certManager": { + "properties": { + "addInjectorAnnotations": { + "type": "boolean" + }, + "cert": { + "properties": { + "annotations": { + "properties": {}, + "type": "object" + }, + "create": { + "type": "boolean" + }, + "duration": { + "type": "string" + }, + "issuerRef": { + "properties": { + "group": { + "type": "string" + }, + "kind": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "type": "object" + }, + "renewBefore": { + "type": "string" + } + }, + "type": "object" + }, + "enabled": { + "type": "boolean" + } + }, + "type": "object" + }, + "create": { + "type": "boolean" + }, + "deploymentAnnotations": { + "properties": {}, + "type": "object" + }, + "extraArgs": { + "properties": {}, + "type": "object" + }, + "extraEnv": { + "type": "array" + }, + "extraVolumeMounts": { + "type": "array" + }, + "extraVolumes": { + "type": "array" + }, + "failurePolicy": { + "type": "string" + }, + "fullnameOverride": { + "type": "string" + }, + "hostNetwork": { + "type": "boolean" + }, + "image": { + "properties": { + "flavour": { + "type": "string" + }, + "pullPolicy": { + "type": "string" + }, + "repository": { + "type": "string" + }, + "tag": { + "type": "string" + } + }, + "type": "object" + }, + "imagePullSecrets": { + "type": "array" + }, + "log": { + "properties": { + "level": { + "type": "string" + }, + "timeEncoding": { + "type": "string" + } + }, + "type": "object" + }, + "lookaheadInterval": { + "type": "string" + }, + "metrics": { + "properties": { + "listen": { + "properties": { + "port": { + "type": "integer" + } + }, + "type": "object" + }, + "service": { + "properties": { + "annotations": { + "properties": {}, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "nameOverride": { + "type": "string" + }, + "nodeSelector": { + "properties": {}, + "type": "object" + }, + "podAnnotations": { + "properties": {}, + "type": "object" + }, + "podDisruptionBudget": { + "properties": { + "enabled": { + "type": "boolean" + }, + "minAvailable": { + "type": "integer" + } + }, + "type": "object" + }, + "podLabels": { + "properties": {}, + "type": "object" + }, + "podSecurityContext": { + "properties": { + "enabled": { + "type": "boolean" + } + }, + "type": "object" + }, + "port": { + "type": "integer" + }, + "priorityClassName": { + "type": "string" + }, + "rbac": { + "properties": { + "create": { + "type": "boolean" + } + }, + "type": "object" + }, + "readinessProbe": { + "properties": { + "address": { + "type": "string" + }, + "port": { + "type": "integer" + } + }, + "type": "object" + }, + "replicaCount": { + "type": "integer" + }, + "resources": { + "properties": {}, + "type": "object" + }, + "revisionHistoryLimit": { + "type": "integer" + }, + "secretAnnotations": { + "properties": {}, + "type": "object" + }, + "securityContext": { + "properties": { + "allowPrivilegeEscalation": { + "type": "boolean" + }, + "capabilities": { + "properties": { + "drop": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "readOnlyRootFilesystem": { + "type": "boolean" + }, + "runAsNonRoot": { + "type": "boolean" + }, + "runAsUser": { + "type": "integer" + }, + "seccompProfile": { + "properties": { + "type": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "serviceAccount": { + "properties": { + "annotations": { + "properties": {}, + "type": "object" + }, + "automount": { + "type": "boolean" + }, + "create": { + "type": "boolean" + }, + "extraLabels": { + "properties": {}, + "type": "object" + }, + "name": { + "type": "string" + } + }, + "type": "object" + }, + "tolerations": { + "type": "array" + }, + "topologySpreadConstraints": { + "type": "array" + } + }, + "type": "object" + } + }, + "type": "object" +} diff --git a/kubernetes-vault/external-secrets/values.yaml b/kubernetes-vault/external-secrets/values.yaml new file mode 100644 index 0000000..19525ad --- /dev/null +++ b/kubernetes-vault/external-secrets/values.yaml @@ -0,0 +1,532 @@ +global: + nodeSelector: {} + tolerations: [] + topologySpreadConstraints: [] + affinity: {} + compatibility: + openshift: + # -- Manages the securityContext properties to make them compatible with OpenShift. + # Possible values: + # auto - Apply configurations if it is detected that OpenShift is the target platform. + # force - Always apply configurations. + # disabled - No modification applied. + adaptSecurityContext: auto + +replicaCount: 1 + +bitwarden-sdk-server: + enabled: false + +# -- Specifies the amount of historic ReplicaSets k8s should keep (see https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#clean-up-policy) +revisionHistoryLimit: 10 + +image: + repository: ghcr.io/external-secrets/external-secrets + pullPolicy: IfNotPresent + # -- The image tag to use. The default is the chart appVersion. + tag: "" + # -- The flavour of tag you want to use + # There are different image flavours available, like distroless and ubi. + # Please see GitHub release notes for image tags for these flavors. + # By default, the distroless image is used. + flavour: "" + +# -- If set, install and upgrade CRDs through helm chart. +installCRDs: true + +crds: + # -- If true, create CRDs for Cluster External Secret. + createClusterExternalSecret: true + # -- If true, create CRDs for Cluster Secret Store. + createClusterSecretStore: true + # -- If true, create CRDs for Push Secret. + createPushSecret: true + annotations: {} + conversion: + enabled: true + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" +namespaceOverride: "" + +# -- Additional labels added to all helm chart resources. +commonLabels: {} + +# -- If true, external-secrets will perform leader election between instances to ensure no more +# than one instance of external-secrets operates at a time. +leaderElect: false + +# -- If set external secrets will filter matching +# Secret Stores with the appropriate controller values. +controllerClass: "" + +# -- If true external secrets will use recommended kubernetes +# annotations as prometheus metric labels. +extendedMetricLabels: false + +# -- If set external secrets are only reconciled in the +# provided namespace +scopedNamespace: "" + +# -- Must be used with scopedNamespace. If true, create scoped RBAC roles under the scoped namespace +# and implicitly disable cluster stores and cluster external secrets +scopedRBAC: false + +# -- if true, the operator will process cluster external secret. Else, it will ignore them. +processClusterExternalSecret: true + +# -- if true, the operator will process cluster store. Else, it will ignore them. +processClusterStore: true + +# -- if true, the operator will process push secret. Else, it will ignore them. +processPushSecret: true + +# -- Specifies whether an external secret operator deployment be created. +createOperator: true + +# -- Specifies the number of concurrent ExternalSecret Reconciles external-secret executes at +# a time. +concurrent: 1 +# -- Specifices Log Params to the Webhook +log: + level: info + timeEncoding: epoch +service: + # -- Set the ip family policy to configure dual-stack see [Configure dual-stack](https://kubernetes.io/docs/concepts/services-networking/dual-stack/#services) + ipFamilyPolicy: "" + # -- Sets the families that should be supported and the order in which they should be applied to ClusterIP as well. Can be IPv4 and/or IPv6. + ipFamilies: [] + +serviceAccount: + # -- Specifies whether a service account should be created. + create: true + # -- Automounts the service account token in all containers of the pod + automount: true + # -- Annotations to add to the service account. + annotations: {} + # -- Extra Labels to add to the service account. + extraLabels: {} + # -- The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template. + name: "" + +rbac: + # -- Specifies whether role and rolebinding resources should be created. + create: true + + servicebindings: + # -- Specifies whether a clusterrole to give servicebindings read access should be created. + create: true + +## -- Extra environment variables to add to container. +extraEnv: [] + +## -- Map of extra arguments to pass to container. +extraArgs: {} + +## -- Extra volumes to pass to pod. +extraVolumes: [] + +## -- Extra Kubernetes objects to deploy with the helm chart +extraObjects: [] + +## -- Extra volumes to mount to the container. +extraVolumeMounts: [] + +## -- Extra containers to add to the pod. +extraContainers: [] + +# -- Annotations to add to Deployment +deploymentAnnotations: {} + +# -- Annotations to add to Pod +podAnnotations: {} + +podLabels: {} + +podSecurityContext: + enabled: true + # fsGroup: 2000 + +securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + enabled: true + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 1000 + seccompProfile: + type: RuntimeDefault + +resources: {} + # requests: + # cpu: 10m + # memory: 32Mi + +serviceMonitor: + # -- Specifies whether to create a ServiceMonitor resource for collecting Prometheus metrics + enabled: false + + # -- namespace where you want to install ServiceMonitors + namespace: "" + + # -- Additional labels + additionalLabels: {} + + # -- Interval to scrape metrics + interval: 30s + + # -- Timeout if metrics can't be retrieved in given time interval + scrapeTimeout: 25s + + # -- Let prometheus add an exported_ prefix to conflicting labels + honorLabels: false + + # -- Metric relabel configs to apply to samples before ingestion. [Metric Relabeling](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs) + metricRelabelings: [] + # - action: replace + # regex: (.*) + # replacement: $1 + # sourceLabels: + # - exported_namespace + # targetLabel: namespace + + # -- Relabel configs to apply to samples before ingestion. [Relabeling](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config) + relabelings: [] + # - sourceLabels: [__meta_kubernetes_pod_node_name] + # separator: ; + # regex: ^(.*)$ + # targetLabel: nodename + # replacement: $1 + # action: replace + +metrics: + + listen: + port: 8080 + + service: + # -- Enable if you use another monitoring tool than Prometheus to scrape the metrics + enabled: false + + # -- Metrics service port to scrape + port: 8080 + + # -- Additional service annotations + annotations: {} + +nodeSelector: {} + +tolerations: [] + +topologySpreadConstraints: [] + +affinity: {} + +# -- Pod priority class name. +priorityClassName: "" + +# -- Pod disruption budget - for more details see https://kubernetes.io/docs/concepts/workloads/pods/disruptions/ +podDisruptionBudget: + enabled: false + minAvailable: 1 + # maxUnavailable: 1 + +# -- Run the controller on the host network +hostNetwork: false + +webhook: + # -- Specifies whether a webhook deployment be created. + create: true + # -- Specifices the time to check if the cert is valid + certCheckInterval: "5m" + # -- Specifices the lookaheadInterval for certificate validity + lookaheadInterval: "" + replicaCount: 1 + # -- Specifices Log Params to the Webhook + log: + level: info + timeEncoding: epoch + # -- Specifies the amount of historic ReplicaSets k8s should keep (see https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#clean-up-policy) + revisionHistoryLimit: 10 + + certDir: /tmp/certs + # -- Specifies whether validating webhooks should be created with failurePolicy: Fail or Ignore + failurePolicy: Fail + # -- Specifies if webhook pod should use hostNetwork or not. + hostNetwork: false + image: + repository: ghcr.io/external-secrets/external-secrets + pullPolicy: IfNotPresent + # -- The image tag to use. The default is the chart appVersion. + tag: "" + # -- The flavour of tag you want to use + flavour: "" + imagePullSecrets: [] + nameOverride: "" + fullnameOverride: "" + # -- The port the webhook will listen to + port: 10250 + rbac: + # -- Specifies whether role and rolebinding resources should be created. + create: true + serviceAccount: + # -- Specifies whether a service account should be created. + create: true + # -- Automounts the service account token in all containers of the pod + automount: true + # -- Annotations to add to the service account. + annotations: {} + # -- Extra Labels to add to the service account. + extraLabels: {} + # -- The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template. + name: "" + nodeSelector: {} + + certManager: + # -- Enabling cert-manager support will disable the built in secret and + # switch to using cert-manager (installed separately) to automatically issue + # and renew the webhook certificate. This chart does not install + # cert-manager for you, See https://cert-manager.io/docs/ + enabled: false + # -- Automatically add the cert-manager.io/inject-ca-from annotation to the + # webhooks and CRDs. As long as you have the cert-manager CA Injector + # enabled, this will automatically setup your webhook's CA to the one used + # by cert-manager. See https://cert-manager.io/docs/concepts/ca-injector + addInjectorAnnotations: true + cert: + # -- Create a certificate resource within this chart. See + # https://cert-manager.io/docs/usage/certificate/ + create: true + # -- For the Certificate created by this chart, setup the issuer. See + # https://cert-manager.io/docs/reference/api-docs/#cert-manager.io/v1.IssuerSpec + issuerRef: + group: cert-manager.io + kind: "Issuer" + name: "my-issuer" + # -- Set the requested duration (i.e. lifetime) of the Certificate. See + # https://cert-manager.io/docs/reference/api-docs/#cert-manager.io/v1.CertificateSpec + # One year by default. + duration: "8760h" + # -- How long before the currently issued certificate’s expiry + # cert-manager should renew the certificate. See + # https://cert-manager.io/docs/reference/api-docs/#cert-manager.io/v1.CertificateSpec + # Note that renewBefore should be greater than .webhook.lookaheadInterval + # since the webhook will check this far in advance that the certificate is + # valid. + renewBefore: "" + # -- Add extra annotations to the Certificate resource. + annotations: {} + + tolerations: [] + + topologySpreadConstraints: [] + + affinity: {} + + # -- Pod priority class name. + priorityClassName: "" + + # -- Pod disruption budget - for more details see https://kubernetes.io/docs/concepts/workloads/pods/disruptions/ + podDisruptionBudget: + enabled: false + minAvailable: 1 + # maxUnavailable: 1 + + metrics: + + listen: + port: 8080 + + service: + # -- Enable if you use another monitoring tool than Prometheus to scrape the metrics + enabled: false + + # -- Metrics service port to scrape + port: 8080 + + # -- Additional service annotations + annotations: {} + + + readinessProbe: + # -- Address for readiness probe + address: "" + # -- ReadinessProbe port for kubelet + port: 8081 + + + ## -- Extra environment variables to add to container. + extraEnv: [] + + ## -- Map of extra arguments to pass to container. + extraArgs: {} + + ## -- Extra volumes to pass to pod. + extraVolumes: [] + + ## -- Extra volumes to mount to the container. + extraVolumeMounts: [] + + # -- Annotations to add to Secret + secretAnnotations: {} + + # -- Annotations to add to Deployment + deploymentAnnotations: {} + + # -- Annotations to add to Pod + podAnnotations: {} + + podLabels: {} + + podSecurityContext: + enabled: true + # fsGroup: 2000 + + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + enabled: true + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 1000 + seccompProfile: + type: RuntimeDefault + + resources: {} + # requests: + # cpu: 10m + # memory: 32Mi + +certController: + # -- Specifies whether a certificate controller deployment be created. + create: true + requeueInterval: "5m" + replicaCount: 1 + # -- Specifices Log Params to the Webhook + log: + level: info + timeEncoding: epoch + # -- Specifies the amount of historic ReplicaSets k8s should keep (see https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#clean-up-policy) + revisionHistoryLimit: 10 + + image: + repository: ghcr.io/external-secrets/external-secrets + pullPolicy: IfNotPresent + tag: "" + flavour: "" + imagePullSecrets: [] + nameOverride: "" + fullnameOverride: "" + rbac: + # -- Specifies whether role and rolebinding resources should be created. + create: true + serviceAccount: + # -- Specifies whether a service account should be created. + create: true + # -- Automounts the service account token in all containers of the pod + automount: true + # -- Annotations to add to the service account. + annotations: {} + # -- Extra Labels to add to the service account. + extraLabels: {} + # -- The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template. + name: "" + nodeSelector: {} + + tolerations: [] + + topologySpreadConstraints: [] + + affinity: {} + + # -- Run the certController on the host network + hostNetwork: false + + # -- Pod priority class name. + priorityClassName: "" + + # -- Pod disruption budget - for more details see https://kubernetes.io/docs/concepts/workloads/pods/disruptions/ + podDisruptionBudget: + enabled: false + minAvailable: 1 + # maxUnavailable: 1 + + metrics: + + listen: + port: 8080 + + service: + # -- Enable if you use another monitoring tool than Prometheus to scrape the metrics + enabled: false + + # -- Metrics service port to scrape + port: 8080 + + # -- Additional service annotations + annotations: {} + + readinessProbe: + # -- Address for readiness probe + address: "" + # -- ReadinessProbe port for kubelet + port: 8081 + + ## -- Extra environment variables to add to container. + extraEnv: [] + + ## -- Map of extra arguments to pass to container. + extraArgs: {} + + + ## -- Extra volumes to pass to pod. + extraVolumes: [] + + ## -- Extra volumes to mount to the container. + extraVolumeMounts: [] + + # -- Annotations to add to Deployment + deploymentAnnotations: {} + + # -- Annotations to add to Pod + podAnnotations: {} + + podLabels: {} + + podSecurityContext: + enabled: true + # fsGroup: 2000 + + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + enabled: true + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 1000 + seccompProfile: + type: RuntimeDefault + + resources: {} + # requests: + # cpu: 10m + # memory: 32Mi + +# -- Specifies `dnsPolicy` to deployment +dnsPolicy: ClusterFirst + +# -- Specifies `dnsOptions` to deployment +dnsConfig: {} + +# -- Any extra pod spec on the deployment +podSpecExtra: {} diff --git a/kubernetes-vault/otus-policy.hcl b/kubernetes-vault/otus-policy.hcl new file mode 100644 index 0000000..4e332fa --- /dev/null +++ b/kubernetes-vault/otus-policy.hcl @@ -0,0 +1,3 @@ +path "otus/*" { + capabilities = ["read", "list"] +} \ No newline at end of file diff --git a/kubernetes-vault/vault-auth-sa.yaml b/kubernetes-vault/vault-auth-sa.yaml new file mode 100644 index 0000000..ad84ced --- /dev/null +++ b/kubernetes-vault/vault-auth-sa.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: vault-auth + namespace: vault +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: vault-auth-delegator +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:auth-delegator +subjects: +- kind: ServiceAccount + name: vault-auth + namespace: vault \ No newline at end of file diff --git a/kubernetes-vault/vault/.helmignore b/kubernetes-vault/vault/.helmignore new file mode 100644 index 0000000..4007e24 --- /dev/null +++ b/kubernetes-vault/vault/.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 +.terraform/ +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj + +# CI and test +.circleci/ +.github/ +.gitlab-ci.yml +test/ diff --git a/kubernetes-vault/vault/CHANGELOG.md b/kubernetes-vault/vault/CHANGELOG.md new file mode 100644 index 0000000..552ee42 --- /dev/null +++ b/kubernetes-vault/vault/CHANGELOG.md @@ -0,0 +1,560 @@ +## Unreleased + +## 0.28.1 (July 11, 2024) + +Changes: + +* Default `vault` version updated to 1.17.2 +* Default `vault-k8s` version updated to 1.4.2 +* Default `vault-csi-provider` version updated to 1.4.3 +* Tested with Kubernetes versions 1.26-1.30 + +Improvements: + +* Configurable `tlsConfig` and `authorization` for Prometheus ServiceMonitor [GH-1025](https://github.com/hashicorp/vault-helm/pull/1025) +* Remove UPDATE from injector-mutating-webhook [GH-783](https://github.com/hashicorp/vault-helm/pull/783) +* Add scope to mutating webhook [GH-1037](https://github.com/hashicorp/vault-helm/pull/1037) + +## 0.28.0 (April 8, 2024) + +Changes: + +* Default `vault` version updated to 1.16.1 +* Default `vault-k8s` version updated to 1.4.1 +* Default `vault-csi-provider` version updated to 1.4.2 +* Tested with Kubernetes versions 1.25-1.29 + +Features: + +* server: Add annotation on config change [GH-1001](https://github.com/hashicorp/vault-helm/pull/1001) + +Bugs: + +* injector: add missing `get` `nodes` permission to ClusterRole [GH-1005](https://github.com/hashicorp/vault-helm/pull/1005) + +## 0.27.0 (November 16, 2023) + +Changes: + +* Default `vault` version updated to 1.15.2 + +Features: + +* server: Support setting `persistentVolumeClaimRetentionPolicy` on the StatefulSet [GH-965](https://github.com/hashicorp/vault-helm/pull/965) +* server: Support setting labels on PVCs [GH-969](https://github.com/hashicorp/vault-helm/pull/969) +* server: Support setting ingress rules for networkPolicy [GH-877](https://github.com/hashicorp/vault-helm/pull/877) + +Improvements: + +* Support exec in the server liveness probe [GH-971](https://github.com/hashicorp/vault-helm/pull/971) + +## 0.26.1 (October 30, 2023) + +Bugs: +* Fix templating of `server.ha.replicas` when set via override file. The `0.26.0` chart would ignore `server.ha.replicas` and always deploy 3 server replicas when `server.ha.enabled=true` unless overridden by command line when issuing the helm command: `--set server.ha.replicas=`. Fixed in [GH-961](https://github.com/hashicorp/vault-helm/pull/961) + +## 0.26.0 (October 27, 2023) + +Changes: +* Default `vault` version updated to 1.15.1 +* Default `vault-k8s` version updated to 1.3.1 +* Default `vault-csi-provider` version updated to 1.4.1 +* Tested with Kubernetes versions 1.24-1.28 +* server: OpenShift default readiness probe returns 204 when uninitialized [GH-966](https://github.com/hashicorp/vault-helm/pull/966) + +Features: +* server: Add support for dual stack clusters [GH-833](https://github.com/hashicorp/vault-helm/pull/833) +* server: Support `hostAliases` for the StatefulSet pods [GH-955](https://github.com/hashicorp/vault-helm/pull/955) +* server: Add `server.service.active.annotations` and `server.service.standby.annotations` [GH-896](https://github.com/hashicorp/vault-helm/pull/896) +* server: Add long-lived service account token option [GH-923](https://github.com/hashicorp/vault-helm/pull/923) + +Bugs: +* csi: Add namespace field to `csi-role` and `csi-rolebindings`. [GH-909](https://github.com/hashicorp/vault-helm/pull/909) + +Improvements: +* global: Add `global.namespace` to override the helm installation namespace. [GH-909](https://github.com/hashicorp/vault-helm/pull/909) +* server: use vault.fullname in Helm test [GH-912](https://github.com/hashicorp/vault-helm/pull/912) +* server: Allow scaling HA replicas to zero [GH-943](https://github.com/hashicorp/vault-helm/pull/943) + +## 0.25.0 (June 26, 2023) + +Changes: +* Latest Kubernetes version tested is now 1.27 +* server: Headless service ignores `server.service.publishNotReadyAddresses` setting and always sets it as `true` [GH-902](https://github.com/hashicorp/vault-helm/pull/902) +* `vault` updated to 1.14.0 [GH-916](https://github.com/hashicorp/vault-helm/pull/916) +* `vault-csi-provider` updated to 1.4.0 [GH-916](https://github.com/hashicorp/vault-helm/pull/916) + +Improvements: +* CSI: Make `nodeSelector` and `affinity` configurable for CSI daemonset's pods [GH-862](https://github.com/hashicorp/vault-helm/pull/862) +* injector: Add `ephemeralLimit` and `ephemeralRequest` as options for configuring Agent's ephemeral storage resources [GH-798](https://github.com/hashicorp/vault-helm/pull/798) +* Minimum kubernetes version for chart reverted to 1.20.0 to allow installation on clusters older than the oldest tested version [GH-916](https://github.com/hashicorp/vault-helm/pull/916) + +Bugs: +* server: Set the default for `prometheusRules.rules` to an empty list [GH-886](https://github.com/hashicorp/vault-helm/pull/886) + +## 0.24.1 (April 17, 2023) + +Bugs: +* csi: Add RBAC required by v1.3.0 to create secret for HMAC key used to generate secret versions [GH-872](https://github.com/hashicorp/vault-helm/pull/872) + +## 0.24.0 (April 6, 2023) + +Changes: +* Earliest Kubernetes version tested is now 1.22 +* `vault` updated to 1.13.1 [GH-863](https://github.com/hashicorp/vault-helm/pull/863) +* `vault-k8s` updated to 1.2.1 [GH-868](https://github.com/hashicorp/vault-helm/pull/868) +* `vault-csi-provider` updated to 1.3.0 [GH-749](https://github.com/hashicorp/vault-helm/pull/749) + +Features: +* server: New `extraPorts` option for adding ports to the Vault server statefulset [GH-841](https://github.com/hashicorp/vault-helm/pull/841) +* server: Add configurable Port Number in readinessProbe and livenessProbe for the server-statefulset [GH-831](https://github.com/hashicorp/vault-helm/pull/831) +* injector: Make livenessProbe and readinessProbe configurable and add configurable startupProbe [GH-852](https://github.com/hashicorp/vault-helm/pull/852) +* csi: Add an Agent sidecar to Vault CSI Provider pods to provide lease caching and renewals [GH-749](https://github.com/hashicorp/vault-helm/pull/749) + +## 0.23.0 (November 28th, 2022) + +Changes: +* `vault` updated to 1.12.1 [GH-814](https://github.com/hashicorp/vault-helm/pull/814) +* `vault-k8s` updated to 1.1.0 [GH-814](https://github.com/hashicorp/vault-helm/pull/814) +* `vault-csi-provider` updated to 1.2.1 [GH-814](https://github.com/hashicorp/vault-helm/pull/814) + +Features: +* server: Add `extraLabels` for Vault server serviceAccount [GH-806](https://github.com/hashicorp/vault-helm/pull/806) +* server: Add `server.service.active.enabled` and `server.service.standby.enabled` options to selectively disable additional services [GH-811](https://github.com/hashicorp/vault-helm/pull/811) +* server: Add `server.serviceAccount.serviceDiscovery.enabled` option to selectively disable a Vault service discovery role and role binding [GH-811](https://github.com/hashicorp/vault-helm/pull/811) +* server: Add `server.service.instanceSelector.enabled` option to allow selecting pods outside the helm chart deployment [GH-813](https://github.com/hashicorp/vault-helm/pull/813) + +Bugs: +* server: Quote `.server.ha.clusterAddr` value [GH-810](https://github.com/hashicorp/vault-helm/pull/810) + +## 0.22.1 (October 26th, 2022) + +Changes: +* `vault` updated to 1.12.0 [GH-803](https://github.com/hashicorp/vault-helm/pull/803) +* `vault-k8s` updated to 1.0.1 [GH-803](https://github.com/hashicorp/vault-helm/pull/803) + +## 0.22.0 (September 8th, 2022) + +Features: +* Add PrometheusOperator support for collecting Vault server metrics. [GH-772](https://github.com/hashicorp/vault-helm/pull/772) + +Changes: +* `vault-k8s` to 1.0.0 [GH-784](https://github.com/hashicorp/vault-helm/pull/784) +* Test against Kubernetes 1.25 [GH-784](https://github.com/hashicorp/vault-helm/pull/784) +* `vault` updated to 1.11.3 [GH-785](https://github.com/hashicorp/vault-helm/pull/785) + +## 0.21.0 (August 10th, 2022) + +CHANGES: +* `vault-k8s` updated to 0.17.0. [GH-771](https://github.com/hashicorp/vault-helm/pull/771) +* `vault-csi-provider` updated to 1.2.0 [GH-771](https://github.com/hashicorp/vault-helm/pull/771) +* `vault` updated to 1.11.2 [GH-771](https://github.com/hashicorp/vault-helm/pull/771) +* Start testing against Kubernetes 1.24. [GH-744](https://github.com/hashicorp/vault-helm/pull/744) +* Deprecated `injector.externalVaultAddr`. Added `global.externalVaultAddr`, which applies to both the Injector and the CSI Provider. [GH-745](https://github.com/hashicorp/vault-helm/pull/745) +* CSI Provider pods now set the `VAULT_ADDR` environment variable to either the internal Vault service or the configured external address. [GH-745](https://github.com/hashicorp/vault-helm/pull/745) + +Features: +* server: Add `server.statefulSet.securityContext` to override pod and container `securityContext`. [GH-767](https://github.com/hashicorp/vault-helm/pull/767) +* csi: Add `csi.daemonSet.securityContext` to override pod and container `securityContext`. [GH-767](https://github.com/hashicorp/vault-helm/pull/767) +* injector: Add `injector.securityContext` to override pod and container `securityContext`. [GH-750](https://github.com/hashicorp/vault-helm/pull/750) and [GH-767](https://github.com/hashicorp/vault-helm/pull/767) +* Add `server.service.activeNodePort` and `server.service.standbyNodePort` to specify the `nodePort` for active and standby services. [GH-610](https://github.com/hashicorp/vault-helm/pull/610) +* Support for setting annotations on the injector's serviceAccount [GH-753](https://github.com/hashicorp/vault-helm/pull/753) + +## 0.20.1 (May 25th, 2022) +CHANGES: +* `vault-k8s` updated to 0.16.1 [GH-739](https://github.com/hashicorp/vault-helm/pull/739) + +Improvements: +* Mutating webhook will no longer target the agent injector pod [GH-736](https://github.com/hashicorp/vault-helm/pull/736) + +Bugs: +* `vault` service account is now created even if the server is set to disabled, as per before 0.20.0 [GH-737](https://github.com/hashicorp/vault-helm/pull/737) + +## 0.20.0 (May 16th, 2022) + +CHANGES: +* `global.enabled` now works as documented, that is, setting `global.enabled` to false will disable everything, with individual components able to be turned on individually [GH-703](https://github.com/hashicorp/vault-helm/pull/703) +* Default value of `-` used for injector and server to indicate that they follow `global.enabled`. [GH-703](https://github.com/hashicorp/vault-helm/pull/703) +* Vault default image to 1.10.3 +* CSI provider default image to 1.1.0 +* Vault K8s default image to 0.16.0 +* Earliest Kubernetes version tested is now 1.16 +* Helm 3.6+ now required + +Features: +* Support topologySpreadConstraints in server and injector. [GH-652](https://github.com/hashicorp/vault-helm/pull/652) + +Improvements: +* CSI: Set `extraLabels` for daemonset, pods, and service account [GH-690](https://github.com/hashicorp/vault-helm/pull/690) +* Add namespace to injector-leader-elector role, rolebinding and secret [GH-683](https://github.com/hashicorp/vault-helm/pull/683) +* Support policy/v1 PodDisruptionBudget in Kubernetes 1.21+ for server and injector [GH-710](https://github.com/hashicorp/vault-helm/pull/710) +* Make the Cluster Address (CLUSTER_ADDR) configurable [GH-629](https://github.com/hashicorp/vault-helm/pull/709) +* server: Make `publishNotReadyAddresses` configurable for services [GH-694](https://github.com/hashicorp/vault-helm/pull/694) +* server: Allow config to be defined as a YAML object in the values file [GH-684](https://github.com/hashicorp/vault-helm/pull/684) +* Maintain default MutatingWebhookConfiguration values from `v1beta1` [GH-692](https://github.com/hashicorp/vault-helm/pull/692) + +## 0.19.0 (January 20th, 2022) + +CHANGES: +* Vault image default 1.9.2 +* Vault K8s image default 0.14.2 + +Features: +* Added configurable podDisruptionBudget for injector [GH-653](https://github.com/hashicorp/vault-helm/pull/653) +* Make terminationGracePeriodSeconds configurable for server [GH-659](https://github.com/hashicorp/vault-helm/pull/659) +* Added configurable update strategy for injector [GH-661](https://github.com/hashicorp/vault-helm/pull/661) +* csi: ability to set priorityClassName for CSI daemonset pods [GH-670](https://github.com/hashicorp/vault-helm/pull/670) + +Improvements: +* Set the namespace on the OpenShift Route [GH-679](https://github.com/hashicorp/vault-helm/pull/679) +* Add volumes and env vars to helm hook test pod [GH-673](https://github.com/hashicorp/vault-helm/pull/673) +* Make TLS configurable for OpenShift routes [GH-686](https://github.com/hashicorp/vault-helm/pull/686) + +## 0.18.0 (November 17th, 2021) + +CHANGES: +* Removed support for deploying a leader-elector container with the [vault-k8s injector](https://github.com/hashicorp/vault-k8s) injector since vault-k8s now uses an internal mechanism to determine leadership [GH-649](https://github.com/hashicorp/vault-helm/pull/649) +* Vault image default 1.9.0 +* Vault K8s image default 0.14.1 + +Improvements: +* Added templateConfig.staticSecretRenderInterval chart option for the injector [GH-621](https://github.com/hashicorp/vault-helm/pull/621) + +## 0.17.1 (October 25th, 2021) + +Improvements: + * Add option for Ingress PathType [GH-634](https://github.com/hashicorp/vault-helm/pull/634) + +## 0.17.0 (October 21st, 2021) + +KNOWN ISSUES: +* The chart will fail to deploy on Kubernetes 1.19+ with `server.ingress.enabled=true` because no `pathType` is set + +CHANGES: +* Vault image default 1.8.4 +* Vault K8s image default 0.14.0 + +Improvements: +* Support Ingress stable networking API [GH-590](https://github.com/hashicorp/vault-helm/pull/590) +* Support setting the `externalTrafficPolicy` for `LoadBalancer` and `NodePort` service types [GH-626](https://github.com/hashicorp/vault-helm/pull/626) +* Support setting ingressClassName on server Ingress [GH-630](https://github.com/hashicorp/vault-helm/pull/630) + +Bugs: +* Ensure `kubeletRootDir` volume path and mounts are the same when `csi.daemonSet.kubeletRootDir` is overridden [GH-628](https://github.com/hashicorp/vault-helm/pull/628) + +## 0.16.1 (September 29th, 2021) + +CHANGES: +* Vault image default 1.8.3 +* Vault K8s image default 0.13.1 + +## 0.16.0 (September 16th, 2021) + +CHANGES: +* Support for deploying a leader-elector container with the [vault-k8s injector](https://github.com/hashicorp/vault-k8s) injector will be removed in version 0.18.0 of this chart since vault-k8s now uses an internal mechanism to determine leadership. To enable the deployment of the leader-elector container for use with vault-k8s 0.12.0 and earlier, set `useContainer=true`. + +Improvements: + * Make CSI provider `hostPaths` configurable via `csi.daemonSet.providersDir` and `csi.daemonSet.kubeletRootDir` [GH-603](https://github.com/hashicorp/vault-helm/pull/603) + * Support vault-k8s internal leader election [GH-568](https://github.com/hashicorp/vault-helm/pull/568) [GH-607](https://github.com/hashicorp/vault-helm/pull/607) + +## 0.15.0 (August 23rd, 2021) + +Improvements: +* Add imagePullSecrets on server test [GH-572](https://github.com/hashicorp/vault-helm/pull/572) +* Add injector.webhookAnnotations chart option [GH-584](https://github.com/hashicorp/vault-helm/pull/584) + +## 0.14.0 (July 28th, 2021) + +Features: +* Added templateConfig.exitOnRetryFailure chart option for the injector [GH-560](https://github.com/hashicorp/vault-helm/pull/560) + +Improvements: +* Support configuring pod tolerations, pod affinity, and node selectors as YAML [GH-565](https://github.com/hashicorp/vault-helm/pull/565) +* Set the default vault image to come from the hashicorp organization [GH-567](https://github.com/hashicorp/vault-helm/pull/567) +* Add support for running the acceptance tests against a local `kind` cluster [GH-567](https://github.com/hashicorp/vault-helm/pull/567) +* Add `server.ingress.activeService` to configure if the ingress should use the active service [GH-570](https://github.com/hashicorp/vault-helm/pull/570) +* Add `server.route.activeService` to configure if the route should use the active service [GH-570](https://github.com/hashicorp/vault-helm/pull/570) +* Support configuring `global.imagePullSecrets` from a string array [GH-576](https://github.com/hashicorp/vault-helm/pull/576) + + +## 0.13.0 (June 17th, 2021) + +Improvements: +* Added a helm test for vault server [GH-531](https://github.com/hashicorp/vault-helm/pull/531) +* Added server.enterpriseLicense option [GH-547](https://github.com/hashicorp/vault-helm/pull/547) +* Added OpenShift overrides [GH-549](https://github.com/hashicorp/vault-helm/pull/549) + +Bugs: +* Fix ui.serviceNodePort schema [GH-537](https://github.com/hashicorp/vault-helm/pull/537) +* Fix server.ha.disruptionBudget.maxUnavailable schema [GH-535](https://github.com/hashicorp/vault-helm/pull/535) +* Added webhook-certs volume mount to sidecar injector [GH-545](https://github.com/hashicorp/vault-helm/pull/545) + +## 0.12.0 (May 25th, 2021) + +Features: +* Pass additional arguments to `vault-csi-provider` using `csi.extraArgs` [GH-526](https://github.com/hashicorp/vault-helm/pull/526) + +Improvements: +* Set chart kubeVersion and added chart-verifier tests [GH-510](https://github.com/hashicorp/vault-helm/pull/510) +* Added values json schema [GH-513](https://github.com/hashicorp/vault-helm/pull/513) +* Ability to set tolerations for CSI daemonset pods [GH-521](https://github.com/hashicorp/vault-helm/pull/521) +* UI target port is now configurable [GH-437](https://github.com/hashicorp/vault-helm/pull/437) + +Bugs: +* CSI: `global.imagePullSecrets` are now also used for CSI daemonset [GH-519](https://github.com/hashicorp/vault-helm/pull/519) + +## 0.11.0 (April 14th, 2021) + +Features: +* Added `server.enabled` to explicitly skip installing a Vault server [GH-486](https://github.com/hashicorp/vault-helm/pull/486) +* Injector now supports enabling host network [GH-471](https://github.com/hashicorp/vault-helm/pull/471) +* Injector port is now configurable [GH-489](https://github.com/hashicorp/vault-helm/pull/489) +* Injector Vault Agent resource defaults are now configurable [GH-493](https://github.com/hashicorp/vault-helm/pull/493) +* Extra paths can now be added to the Vault ingress service [GH-460](https://github.com/hashicorp/vault-helm/pull/460) +* Log level and format can now be set directly using `server.logFormat` and `server.logLevel` [GH-488](https://github.com/hashicorp/vault-helm/pull/488) + +Improvements: +* Added `https` name to injector service port [GH-495](https://github.com/hashicorp/vault-helm/pull/495) + +Bugs: +* CSI: Fix ClusterRole name and DaemonSet's service account to properly match deployment name [GH-486](https://github.com/hashicorp/vault-helm/pull/486) + +## 0.10.0 (March 25th, 2021) + +Features: +* Add support for [Vault CSI provider](https://github.com/hashicorp/vault-csi-provider) [GH-461](https://github.com/hashicorp/vault-helm/pull/461) + +Improvements: +* `objectSelector` can now be set on the mutating admission webhook [GH-456](https://github.com/hashicorp/vault-helm/pull/456) + +## 0.9.1 (February 2nd, 2021) + +Bugs: +* Injector: fix labels for default anti-affinity rule [GH-441](https://github.com/hashicorp/vault-helm/pull/441), [GH-442](https://github.com/hashicorp/vault-helm/pull/442) +* Set VAULT_DEV_LISTEN_ADDRESS in dev mode [GH-446](https://github.com/hashicorp/vault-helm/pull/446) + +## 0.9.0 (January 5th, 2021) + +Features: +* Injector now supports configurable number of replicas [GH-436](https://github.com/hashicorp/vault-helm/pull/436) +* Injector now supports auto TLS for multiple replicas using leader elections [GH-436](https://github.com/hashicorp/vault-helm/pull/436) + +Improvements: +* Dev mode now supports `server.extraArgs` [GH-421](https://github.com/hashicorp/vault-helm/pull/421) +* Dev mode root token is now configurable with `server.dev.devRootToken` [GH-415](https://github.com/hashicorp/vault-helm/pull/415) +* ClusterRoleBinding updated to `v1` [GH-395](https://github.com/hashicorp/vault-helm/pull/395) +* MutatingWebhook updated to `v1` [GH-408](https://github.com/hashicorp/vault-helm/pull/408) +* Injector service now supports `injector.service.annotations` [425](https://github.com/hashicorp/vault-helm/pull/425) +* Injector now supports `injector.extraLabels` [428](https://github.com/hashicorp/vault-helm/pull/428) +* Added `allowPrivilegeEscalation: false` to Vault and Injector containers [429](https://github.com/hashicorp/vault-helm/pull/429) +* Network Policy now supports `server.networkPolicy.egress` [389](https://github.com/hashicorp/vault-helm/pull/389) + +## 0.8.0 (October 20th, 2020) + +Improvements: +* Make server NetworkPolicy independent of OpenShift [GH-381](https://github.com/hashicorp/vault-helm/pull/381) +* Added configurables for all probe values [GH-387](https://github.com/hashicorp/vault-helm/pull/387) +* MountPath for audit and data storage is now configurable [GH-393](https://github.com/hashicorp/vault-helm/pull/393) +* Annotations can now be added to the Injector pods [GH-394](https://github.com/hashicorp/vault-helm/pull/394) +* The injector can now be configured with a failurePolicy [GH-400](https://github.com/hashicorp/vault-helm/pull/400) +* Added additional environment variables for rendering within Vault config [GH-398](https://github.com/hashicorp/vault-helm/pull/398) +* Service account for Vault K8s auth is automatically created when `injector.externalVaultAddr` is set [GH-392](https://github.com/hashicorp/vault-helm/pull/392) + +Bugs: +* Fixed install output using Helm V2 command [GH-378](https://github.com/hashicorp/vault-helm/pull/378) + +## 0.7.0 (August 24th, 2020) + +Features: +* Added `volumes` and `volumeMounts` for mounting _any_ type of volume [GH-314](https://github.com/hashicorp/vault-helm/pull/314). +* Added configurable to enable prometheus telemetery exporter for Vault Agent Injector [GH-372](https://github.com/hashicorp/vault-helm/pull/372) + +Improvements: +* Added `defaultMode` configurable to `extraVolumes`[GH-321](https://github.com/hashicorp/vault-helm/pull/321) +* Option to install and use PodSecurityPolicy's for vault server and injector [GH-177](https://github.com/hashicorp/vault-helm/pull/177) +* `VAULT_API_ADDR` is now configurable [GH-290](https://github.com/hashicorp/vault-helm/pull/290) +* Removed deprecated tolerate unready endpoint annotations [GH-363](https://github.com/hashicorp/vault-helm/pull/363) +* Add an option to set annotations on the StatefulSet [GH-199](https://github.com/hashicorp/vault-helm/pull/199) +* Make the vault server serviceAccount name a configuration option [GH-367](https://github.com/hashicorp/vault-helm/pull/367) +* Removed annotation striction from `dev` mode [GH-371](https://github.com/hashicorp/vault-helm/pull/371) +* Add an option to set annotations on PVCs [GH-364](https://github.com/hashicorp/vault-helm/pull/364) +* Added service configurables for UI [GH-285](https://github.com/hashicorp/vault-helm/pull/285) + +Bugs: +* Fix python dependency in test image [GH-337](https://github.com/hashicorp/vault-helm/pull/337) +* Fix caBundle not being quoted causing validation issues with Helm 3 [GH-352](https://github.com/hashicorp/vault-helm/pull/352) +* Fix injector network policy being rendered when injector is not enabled [GH-358](https://github.com/hashicorp/vault-helm/pull/358) + +## 0.6.0 (June 3rd, 2020) + +Features: +* Added `extraInitContainers` to define init containers for the Vault cluster [GH-258](https://github.com/hashicorp/vault-helm/pull/258) +* Added `postStart` lifecycle hook allowing users to configure commands to run on the Vault pods after they're ready [GH-315](https://github.com/hashicorp/vault-helm/pull/315) +* Beta: Added OpenShift support [GH-319](https://github.com/hashicorp/vault-helm/pull/319) + +Improvements: +* Server configs can now be defined in YAML. Multi-line string configs are still compatible [GH-213](https://github.com/hashicorp/vault-helm/pull/213) +* Removed IPC_LOCK privileges since swap is disabled on containers [[GH-198](https://github.com/hashicorp/vault-helm/pull/198)] +* Use port names that map to vault.scheme [[GH-223](https://github.com/hashicorp/vault-helm/pull/223)] +* Allow both yaml and multi-line string annotations [[GH-272](https://github.com/hashicorp/vault-helm/pull/272)] +* Added configurable to set the Raft node name to hostname [[GH-269](https://github.com/hashicorp/vault-helm/pull/269)] +* Support setting priorityClassName on pods [[GH-282](https://github.com/hashicorp/vault-helm/pull/282)] +* Added support for ingress apiVersion `networking.k8s.io/v1beta1` [[GH-310](https://github.com/hashicorp/vault-helm/pull/310)] +* Added configurable to change service type for the HA active service [GH-317](https://github.com/hashicorp/vault-helm/pull/317) + +Bugs: +* Fixed default ingress path [[GH-224](https://github.com/hashicorp/vault-helm/pull/224)] +* Fixed annotations for HA standby/active services [[GH-268](https://github.com/hashicorp/vault-helm/pull/268)] +* Updated some value defaults to match their use in templates [[GH-309](https://github.com/hashicorp/vault-helm/pull/309)] +* Use active service on ingress when ha [[GH-270](https://github.com/hashicorp/vault-helm/pull/270)] +* Fixed bug where pull secrets weren't being used for injector image [GH-298](https://github.com/hashicorp/vault-helm/pull/298) + +## 0.5.0 (April 9th, 2020) + +Features: + +* Added Raft support for HA mode [[GH-228](https://github.com/hashicorp/vault-helm/pull/229)] +* Now supports Vault Enterprise [[GH-250](https://github.com/hashicorp/vault-helm/pull/250)] +* Added K8s Service Registration for HA modes [[GH-250](https://github.com/hashicorp/vault-helm/pull/250)] + +* Option to set `AGENT_INJECT_VAULT_AUTH_PATH` for the injector [[GH-185](https://github.com/hashicorp/vault-helm/pull/185)] +* Added environment variables for logging and revocation on Vault Agent Injector [[GH-219](https://github.com/hashicorp/vault-helm/pull/219)] +* Option to set environment variables for the injector deployment [[GH-232](https://github.com/hashicorp/vault-helm/pull/232)] +* Added affinity, tolerations, and nodeSelector options for the injector deployment [[GH-234](https://github.com/hashicorp/vault-helm/pull/234)] +* Made all annotations multi-line strings [[GH-227](https://github.com/hashicorp/vault-helm/pull/227)] + +## 0.4.0 (February 21st, 2020) + +Improvements: + +* Allow process namespace sharing between Vault and sidecar containers [[GH-174](https://github.com/hashicorp/vault-helm/pull/174)] +* Added configurable to change updateStrategy [[GH-172](https://github.com/hashicorp/vault-helm/pull/172)] +* Added sleep in the preStop lifecycle step [[GH-188](https://github.com/hashicorp/vault-helm/pull/188)] +* Updated chart and tests to Helm 3 [[GH-195](https://github.com/hashicorp/vault-helm/pull/195)] +* Adds Values.injector.externalVaultAddr to use the injector with an external vault [[GH-207](https://github.com/hashicorp/vault-helm/pull/207)] + +Bugs: + +* Fix bug where Vault lifecycle was appended after extra containers. [[GH-179](https://github.com/hashicorp/vault-helm/pull/179)] + +## 0.3.3 (January 14th, 2020) + +Security: + +* Added `server.extraArgs` to allow loading of additional Vault configurations containing sensitive settings [GH-175](https://github.com/hashicorp/vault-helm/issues/175) + +Bugs: + +* Fixed injection bug where wrong environment variables were being used for manually mounted TLS files + +## 0.3.2 (January 8th, 2020) + +Bugs: + +* Fixed injection bug where TLS Skip Verify was true by default [VK8S-35] + +## 0.3.1 (January 2nd, 2020) + +Bugs: + +* Fixed injection bug causing kube-system pods to be rejected [VK8S-14] + +## 0.3.0 (December 19th, 2019) + +Features: + +* Extra containers can now be added to the Vault pods +* Added configurability of pod probes +* Added Vault Agent Injector + +Improvements: + +* Moved `global.image` to `server.image` +* Changed UI service template to route pods that aren't ready via `publishNotReadyAddresses: true` +* Added better HTTP/HTTPS scheme support to http probes +* Added configurable node port for Vault service +* `server.authDelegator` is now enabled by default + +Bugs: + +* Fixed upgrade bug by removing chart label which contained the version +* Fixed typo on `serviceAccount` (was `serviceaccount`) +* Fixed readiness/liveliness HTTP probe default to accept standbys + +## 0.2.1 (November 12th, 2019) + +Bugs: + +* Removed `readOnlyRootFilesystem` causing issues when validating deployments + +## 0.2.0 (October 29th, 2019) + +Features: + +* Added load balancer support +* Added ingress support +* Added configurable for service types (ClusterIP, NodePort, LoadBalancer, etc) +* Removed root requirements, now runs as Vault user + +Improvements: + +* Added namespace value to all rendered objects +* Made ports configurable in services +* Added the ability to add custom annotations to services +* Added docker image for running bats test in CircleCI +* Removed restrictions around `dev` mode such as annotations +* `readOnlyRootFilesystem` is now configurable +* Image Pull Policy is now configurable + +Bugs: + +* Fixed selector bugs related to Helm label updates (services, affinities, and pod disruption) +* Fixed bug where audit storage was not being mounted in HA mode +* Fixed bug where Vault pod wasn't receiving SIGTERM signals + + +## 0.1.2 (August 22nd, 2019) + +Features: + +* Added `extraSecretEnvironmentVars` to allow users to mount secrets as + environment variables +* Added `tlsDisable` configurable to change HTTP protocols from HTTP/HTTPS + depending on the value +* Added `serviceNodePort` to configure a NodePort value when setting `serviceType` + to "NodePort" + +Improvements: + +* Changed UI port to 8200 for better HTTP protocol support +* Added `path` to `extraVolumes` to define where the volume should be + mounted. Defaults to `/vault/userconfig` +* Upgraded Vault to 1.2.2 + +Bugs: + +* Fixed bug where upgrade would fail because immutable labels were being + changed (Helm Version label) +* Fixed bug where UI service used wrong selector after updating helm labels +* Added `VAULT_API_ADDR` env to Vault pod to fixed bug where Vault thinks + Consul is the active node +* Removed `step-down` preStop since it requires authentication. Shutdown signal + sent by Kube acts similar to `step-down` + + +## 0.1.1 (August 7th, 2019) + +Features: + +* Added `authDelegator` Cluster Role Binding to Vault service account for + bootstrapping Kube auth method + +Improvements: + +* Added `server.service.clusterIP` to `values.yml` so users can toggle + the Vault service to headless by using the value `None`. +* Upgraded Vault to 1.2.1 + +## 0.1.0 (August 6th, 2019) + +Initial release diff --git a/kubernetes-vault/vault/CODEOWNERS b/kubernetes-vault/vault/CODEOWNERS new file mode 100644 index 0000000..a765f7e --- /dev/null +++ b/kubernetes-vault/vault/CODEOWNERS @@ -0,0 +1 @@ +* @hashicorp/vault-ecosystem diff --git a/kubernetes-vault/vault/CONTRIBUTING.md b/kubernetes-vault/vault/CONTRIBUTING.md new file mode 100644 index 0000000..ad31ac9 --- /dev/null +++ b/kubernetes-vault/vault/CONTRIBUTING.md @@ -0,0 +1,247 @@ +# Contributing to Vault Helm + +**Please note:** We take Vault's security and our users' trust very seriously. +If you believe you have found a security issue in Vault, please responsibly +disclose by contacting us at security@hashicorp.com. + +**First:** if you're unsure or afraid of _anything_, just ask or submit the +issue or pull request anyways. You won't be yelled at for giving it your best +effort. The worst that can happen is that you'll be politely asked to change +something. We appreciate any sort of contributions, and don't want a wall of +rules to get in the way of that. + +That said, if you want to ensure that a pull request is likely to be merged, +talk to us! You can find out our thoughts and ensure that your contribution +won't clash or be obviated by Vault's normal direction. A great way to do this +is via the [Vault Discussion Forum][1]. + +This document will cover what we're looking for in terms of reporting issues. +By addressing all the points we're looking for, it raises the chances we can +quickly merge or address your contributions. + +[1]: https://discuss.hashicorp.com/c/vault + +## Issues + +### Reporting an Issue + +* Make sure you test against the latest released version. It is possible + we already fixed the bug you're experiencing. Even better is if you can test + against `main`, as bugs are fixed regularly but new versions are only + released every few months. + +* Provide steps to reproduce the issue, and if possible include the expected + results as well as the actual results. Please provide text, not screen shots! + +* Respond as promptly as possible to any questions made by the Vault + team to your issue. Stale issues will be closed periodically. + +### Issue Lifecycle + +1. The issue is reported. + +2. The issue is verified and categorized by a Vault Helm collaborator. + Categorization is done via tags. For example, bugs are marked as "bugs". + +3. Unless it is critical, the issue may be left for a period of time (sometimes + many weeks), giving outside contributors -- maybe you!? -- a chance to + address the issue. + +4. The issue is addressed in a pull request or commit. The issue will be + referenced in the commit message so that the code that fixes it is clearly + linked. + +5. The issue is closed. Sometimes, valid issues will be closed to keep + the issue tracker clean. The issue is still indexed and available for + future viewers, or can be re-opened if necessary. + +## Testing + +The Helm chart ships with both unit and acceptance tests. + +The unit tests don't require any active Kubernetes cluster and complete +very quickly. These should be used for fast feedback during development. +The acceptance tests require a Kubernetes cluster with a configured `kubectl`. + +### Test Using Docker Container + +The following are the instructions for running bats tests using a Docker container. + +#### Prerequisites + +* Docker installed +* `vault-helm` checked out locally + +#### Test + +**Note:** the following commands should be run from the `vault-helm` directory. + +First, build the Docker image for running the tests: + +```shell +docker build -f ${PWD}/test/docker/Test.dockerfile ${PWD}/test/docker/ -t vault-helm-test +``` +Next, execute the tests with the following commands: +```shell +docker run -it --rm -v "${PWD}:/test" vault-helm-test bats /test/test/unit +``` +It's possible to only run specific bats tests using regular expressions. +For example, the following will run only tests with "injector" in the name: +```shell +docker run -it --rm -v "${PWD}:/test" vault-helm-test bats /test/test/unit -f "injector" +``` + +### Test Manually +The following are the instructions for running bats tests on your workstation. +#### Prerequisites +* [Bats](https://github.com/bats-core/bats-core) + ```bash + brew install bats-core + ``` +* [yq](https://pypi.org/project/yq/) + ```bash + brew install python-yq + ``` +* [helm](https://helm.sh) + ```bash + brew install kubernetes-helm + ``` + +#### Test + +To run the unit tests: + + bats ./test/unit + +To run the acceptance tests: + + bats ./test/acceptance + +If the acceptance tests fail, deployed resources in the Kubernetes cluster +may not be properly cleaned up. We recommend recycling the Kubernetes cluster to +start from a clean slate. + +**Note:** There is a Terraform configuration in the +[`test/terraform/`](https://github.com/hashicorp/vault-helm/tree/main/test/terraform) directory +that can be used to quickly bring up a GKE cluster and configure +`kubectl` and `helm` locally. This can be used to quickly spin up a test +cluster for acceptance tests. Unit tests _do not_ require a running Kubernetes +cluster. + +### Writing Unit Tests + +Changes to the Helm chart should be accompanied by appropriate unit tests. + +#### Formatting + +- Put tests in the test file in the same order as the variables appear in the `values.yaml`. +- Start tests for a chart value with a header that says what is being tested, like this: + ``` + #-------------------------------------------------------------------- + # annotations + ``` + +- Name the test based on what it's testing in the following format (this will be its first line): + ``` + @test "
: " { + ``` + + When adding tests to an existing file, the first section will be the same as the other tests in the file. + +#### Test Details + +[Bats](https://github.com/bats-core/bats-core) provides a way to run commands in a shell and inspect the output in an automated way. +In all of the tests in this repo, the base command being run is [helm template](https://docs.helm.sh/helm/#helm-template) which turns the templated files into straight yaml output. +In this way, we're able to test that the various conditionals in the templates render as we would expect. + +Each test defines the files that should be rendered using the `--show-only` flag, then it might adjust chart values by adding `--set` flags as well. +The output from this `helm template` command is then piped to [yq](https://pypi.org/project/yq/). +`yq` allows us to pull out just the information we're interested in, either by referencing its position in the yaml file directly or giving information about it (like its length). +The `-r` flag can be used with `yq` to return a raw string instead of a quoted one which is especially useful when looking for an exact match. + +The test passes or fails based on the conditional at the end that is in square brackets, which is a comparison of our expected value and the output of `helm template` piped to `yq`. + +The `| tee /dev/stderr ` pieces direct any terminal output of the `helm template` and `yq` commands to stderr so that it doesn't interfere with `bats`. + +#### Test Examples + +Here are some examples of common test patterns: + +- Check that a value is disabled by default + + ``` + @test "ui/Service: no type by default" { + cd `chart_dir` + local actual=$(helm template \ + --show-only templates/ui-service.yaml \ + . | tee /dev/stderr | + yq -r '.spec.type' | tee /dev/stderr) + [ "${actual}" = "null" ] + } + ``` + + In this example, nothing is changed from the default templates (no `--set` flags), then we use `yq` to retrieve the value we're checking, `.spec.type`. + This output is then compared against our expected value (`null` in this case) in the assertion `[ "${actual}" = "null" ]`. + + +- Check that a template value is rendered to a specific value + ``` + @test "ui/Service: specified type" { + cd `chart_dir` + local actual=$(helm template \ + --show-only templates/ui-service.yaml \ + --set 'ui.serviceType=LoadBalancer' \ + . | tee /dev/stderr | + yq -r '.spec.type' | tee /dev/stderr) + [ "${actual}" = "LoadBalancer" ] + } + ``` + + This is very similar to the last example, except we've changed a default value with the `--set` flag and correspondingly changed the expected value. + +- Check that a template value contains several values + ``` + @test "server/standalone-StatefulSet: custom resources" { + cd `chart_dir` + local actual=$(helm template \ + --show-only templates/server-statefulset.yaml \ + --set 'server.standalone.enabled=true' \ + --set 'server.resources.requests.memory=256Mi' \ + --set 'server.resources.requests.cpu=250m' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].resources.requests.memory' | tee /dev/stderr) + [ "${actual}" = "256Mi" ] + + local actual=$(helm template \ + --show-only templates/server-statefulset.yaml \ + --set 'server.standalone.enabled=true' \ + --set 'server.resources.limits.memory=256Mi' \ + --set 'server.resources.limits.cpu=250m' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].resources.limits.memory' | tee /dev/stderr) + [ "${actual}" = "256Mi" ] + ``` + + *Note:* If testing more than two conditions, it would be good to separate the `helm template` part of the command from the `yq` sections to reduce redundant work. + +- Check that an entire template file is not rendered + ``` + @test "syncCatalog/Deployment: disabled by default" { + cd `chart_dir` + local actual=$( (helm template \ + --show-only templates/server-statefulset.yaml \ + --set 'global.enabled=false' \ + . || echo "---") | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] + } + ``` + Here we are check the length of the command output to see if the anything is rendered. + This style can easily be switched to check that a file is rendered instead. + +## Contributor License Agreement + +We require that all contributors sign our Contributor License Agreement ("CLA") +before we can accept the contribution. + +[Learn more about why HashiCorp requires a CLA and what the CLA includes](https://www.hashicorp.com/cla) diff --git a/kubernetes-vault/vault/Chart.yaml b/kubernetes-vault/vault/Chart.yaml new file mode 100644 index 0000000..86235d3 --- /dev/null +++ b/kubernetes-vault/vault/Chart.yaml @@ -0,0 +1,23 @@ +annotations: + charts.openshift.io/name: HashiCorp Vault +apiVersion: v2 +appVersion: 1.17.2 +description: Official HashiCorp Vault Chart +home: https://www.vaultproject.io +icon: https://github.com/hashicorp/vault/raw/f22d202cde2018f9455dec755118a9b84586e082/Vault_PrimaryLogo_Black.png +keywords: +- vault +- security +- encryption +- secrets +- management +- automation +- infrastructure +kubeVersion: '>= 1.20.0-0' +name: vault +sources: +- https://github.com/hashicorp/vault +- https://github.com/hashicorp/vault-helm +- https://github.com/hashicorp/vault-k8s +- https://github.com/hashicorp/vault-csi-provider +version: 0.28.1 diff --git a/kubernetes-vault/vault/LICENSE b/kubernetes-vault/vault/LICENSE new file mode 100644 index 0000000..74f38c0 --- /dev/null +++ b/kubernetes-vault/vault/LICENSE @@ -0,0 +1,355 @@ +Copyright (c) 2018 HashiCorp, Inc. + +Mozilla Public License, version 2.0 + +1. Definitions + +1.1. “Contributor” + + means each individual or legal entity that creates, contributes to the + creation of, or owns Covered Software. + +1.2. “Contributor Version” + + means the combination of the Contributions of others (if any) used by a + Contributor and that particular Contributor’s Contribution. + +1.3. “Contribution” + + means Covered Software of a particular Contributor. + +1.4. “Covered Software” + + means Source Code Form to which the initial Contributor has attached the + notice in Exhibit A, the Executable Form of such Source Code Form, and + Modifications of such Source Code Form, in each case including portions + thereof. + +1.5. “Incompatible With Secondary Licenses” + means + + a. that the initial Contributor has attached the notice described in + Exhibit B to the Covered Software; or + + b. that the Covered Software was made available under the terms of version + 1.1 or earlier of the License, but not also under the terms of a + Secondary License. + +1.6. “Executable Form” + + means any form of the work other than Source Code Form. + +1.7. “Larger Work” + + means a work that combines Covered Software with other material, in a separate + file or files, that is not Covered Software. + +1.8. “License” + + means this document. + +1.9. “Licensable” + + means having the right to grant, to the maximum extent possible, whether at the + time of the initial grant or subsequently, any and all of the rights conveyed by + this License. + +1.10. “Modifications” + + means any of the following: + + a. any file in Source Code Form that results from an addition to, deletion + from, or modification of the contents of Covered Software; or + + b. any new file in Source Code Form that contains any Covered Software. + +1.11. “Patent Claims” of a Contributor + + means any patent claim(s), including without limitation, method, process, + and apparatus claims, in any patent Licensable by such Contributor that + would be infringed, but for the grant of the License, by the making, + using, selling, offering for sale, having made, import, or transfer of + either its Contributions or its Contributor Version. + +1.12. “Secondary License” + + means either the GNU General Public License, Version 2.0, the GNU Lesser + General Public License, Version 2.1, the GNU Affero General Public + License, Version 3.0, or any later versions of those licenses. + +1.13. “Source Code Form” + + means the form of the work preferred for making modifications. + +1.14. “You” (or “Your”) + + means an individual or a legal entity exercising rights under this + License. For legal entities, “You” includes any entity that controls, is + controlled by, or is under common control with You. For purposes of this + definition, “control” means (a) the power, direct or indirect, to cause + the direction or management of such entity, whether by contract or + otherwise, or (b) ownership of more than fifty percent (50%) of the + outstanding shares or beneficial ownership of such entity. + + +2. License Grants and Conditions + +2.1. Grants + + Each Contributor hereby grants You a world-wide, royalty-free, + non-exclusive license: + + a. under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or as + part of a Larger Work; and + + b. under Patent Claims of such Contributor to make, use, sell, offer for + sale, have made, import, and otherwise transfer either its Contributions + or its Contributor Version. + +2.2. Effective Date + + The licenses granted in Section 2.1 with respect to any Contribution become + effective for each Contribution on the date the Contributor first distributes + such Contribution. + +2.3. Limitations on Grant Scope + + The licenses granted in this Section 2 are the only rights granted under this + License. No additional rights or licenses will be implied from the distribution + or licensing of Covered Software under this License. Notwithstanding Section + 2.1(b) above, no patent license is granted by a Contributor: + + a. for any code that a Contributor has removed from Covered Software; or + + b. for infringements caused by: (i) Your and any other third party’s + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + + c. under Patent Claims infringed by Covered Software in the absence of its + Contributions. + + This License does not grant any rights in the trademarks, service marks, or + logos of any Contributor (except as may be necessary to comply with the + notice requirements in Section 3.4). + +2.4. Subsequent Licenses + + No Contributor makes additional grants as a result of Your choice to + distribute the Covered Software under a subsequent version of this License + (see Section 10.2) or under the terms of a Secondary License (if permitted + under the terms of Section 3.3). + +2.5. Representation + + Each Contributor represents that the Contributor believes its Contributions + are its original creation(s) or it has sufficient rights to grant the + rights to its Contributions conveyed by this License. + +2.6. Fair Use + + This License is not intended to limit any rights You have under applicable + copyright doctrines of fair use, fair dealing, or other equivalents. + +2.7. Conditions + + Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in + Section 2.1. + + +3. Responsibilities + +3.1. Distribution of Source Form + + All distribution of Covered Software in Source Code Form, including any + Modifications that You create or to which You contribute, must be under the + terms of this License. You must inform recipients that the Source Code Form + of the Covered Software is governed by the terms of this License, and how + they can obtain a copy of this License. You may not attempt to alter or + restrict the recipients’ rights in the Source Code Form. + +3.2. Distribution of Executable Form + + If You distribute Covered Software in Executable Form then: + + a. such Covered Software must also be made available in Source Code Form, + as described in Section 3.1, and You must inform recipients of the + Executable Form how they can obtain a copy of such Source Code Form by + reasonable means in a timely manner, at a charge no more than the cost + of distribution to the recipient; and + + b. You may distribute such Executable Form under the terms of this License, + or sublicense it under different terms, provided that the license for + the Executable Form does not attempt to limit or alter the recipients’ + rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + + You may create and distribute a Larger Work under terms of Your choice, + provided that You also comply with the requirements of this License for the + Covered Software. If the Larger Work is a combination of Covered Software + with a work governed by one or more Secondary Licenses, and the Covered + Software is not Incompatible With Secondary Licenses, this License permits + You to additionally distribute such Covered Software under the terms of + such Secondary License(s), so that the recipient of the Larger Work may, at + their option, further distribute the Covered Software under the terms of + either this License or such Secondary License(s). + +3.4. Notices + + You may not remove or alter the substance of any license notices (including + copyright notices, patent notices, disclaimers of warranty, or limitations + of liability) contained within the Source Code Form of the Covered + Software, except that You may alter any license notices to the extent + required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + + You may choose to offer, and to charge a fee for, warranty, support, + indemnity or liability obligations to one or more recipients of Covered + Software. However, You may do so only on Your own behalf, and not on behalf + of any Contributor. You must make it absolutely clear that any such + warranty, support, indemnity, or liability obligation is offered by You + alone, and You hereby agree to indemnify every Contributor for any + liability incurred by such Contributor as a result of warranty, support, + indemnity or liability terms You offer. You may include additional + disclaimers of warranty and limitations of liability specific to any + jurisdiction. + +4. Inability to Comply Due to Statute or Regulation + + If it is impossible for You to comply with any of the terms of this License + with respect to some or all of the Covered Software due to statute, judicial + order, or regulation then You must: (a) comply with the terms of this License + to the maximum extent possible; and (b) describe the limitations and the code + they affect. Such description must be placed in a text file included with all + distributions of the Covered Software under this License. Except to the + extent prohibited by statute or regulation, such description must be + sufficiently detailed for a recipient of ordinary skill to be able to + understand it. + +5. Termination + +5.1. The rights granted under this License will terminate automatically if You + fail to comply with any of its terms. However, if You become compliant, + then the rights granted under this License from a particular Contributor + are reinstated (a) provisionally, unless and until such Contributor + explicitly and finally terminates Your grants, and (b) on an ongoing basis, + if such Contributor fails to notify You of the non-compliance by some + reasonable means prior to 60 days after You have come back into compliance. + Moreover, Your grants from a particular Contributor are reinstated on an + ongoing basis if such Contributor notifies You of the non-compliance by + some reasonable means, this is the first time You have received notice of + non-compliance with this License from such Contributor, and You become + compliant prior to 30 days after Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent + infringement claim (excluding declaratory judgment actions, counter-claims, + and cross-claims) alleging that a Contributor Version directly or + indirectly infringes any patent, then the rights granted to You by any and + all Contributors for the Covered Software under Section 2.1 of this License + shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user + license agreements (excluding distributors and resellers) which have been + validly granted by You or Your distributors under this License prior to + termination shall survive termination. + +6. Disclaimer of Warranty + + Covered Software is provided under this License on an “as is” basis, without + warranty of any kind, either expressed, implied, or statutory, including, + without limitation, warranties that the Covered Software is free of defects, + merchantable, fit for a particular purpose or non-infringing. The entire + risk as to the quality and performance of the Covered Software is with You. + Should any Covered Software prove defective in any respect, You (not any + Contributor) assume the cost of any necessary servicing, repair, or + correction. This disclaimer of warranty constitutes an essential part of this + License. No use of any Covered Software is authorized under this License + except under this disclaimer. + +7. Limitation of Liability + + Under no circumstances and under no legal theory, whether tort (including + negligence), contract, or otherwise, shall any Contributor, or anyone who + distributes Covered Software as permitted above, be liable to You for any + direct, indirect, special, incidental, or consequential damages of any + character including, without limitation, damages for lost profits, loss of + goodwill, work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses, even if such party shall have been + informed of the possibility of such damages. This limitation of liability + shall not apply to liability for death or personal injury resulting from such + party’s negligence to the extent applicable law prohibits such limitation. + Some jurisdictions do not allow the exclusion or limitation of incidental or + consequential damages, so this exclusion and limitation may not apply to You. + +8. Litigation + + Any litigation relating to this License may be brought only in the courts of + a jurisdiction where the defendant maintains its principal place of business + and such litigation shall be governed by laws of that jurisdiction, without + reference to its conflict-of-law provisions. Nothing in this Section shall + prevent a party’s ability to bring cross-claims or counter-claims. + +9. Miscellaneous + + This License represents the complete agreement concerning the subject matter + hereof. If any provision of this License is held to be unenforceable, such + provision shall be reformed only to the extent necessary to make it + enforceable. Any law or regulation which provides that the language of a + contract shall be construed against the drafter shall not be used to construe + this License against a Contributor. + + +10. Versions of the License + +10.1. New Versions + + Mozilla Foundation is the license steward. Except as provided in Section + 10.3, no one other than the license steward has the right to modify or + publish new versions of this License. Each version will be given a + distinguishing version number. + +10.2. Effect of New Versions + + You may distribute the Covered Software under the terms of the version of + the License under which You originally received the Covered Software, or + under the terms of any subsequent version published by the license + steward. + +10.3. Modified Versions + + If you create software not governed by this License, and you want to + create a new license for such software, you may create and use a modified + version of this License if you rename the license and remove any + references to the name of the license steward (except to note that such + modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses + If You choose to distribute Source Code Form that is Incompatible With + Secondary Licenses under the terms of this version of the License, the + notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice + + This Source Code Form is subject to the + terms of the Mozilla Public License, v. + 2.0. If a copy of the MPL was not + distributed with this file, You can + obtain one at + http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular file, then +You may include the notice in a location (such as a LICENSE file in a relevant +directory) where a recipient would be likely to look for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - “Incompatible With Secondary Licenses” Notice + + This Source Code Form is “Incompatible + With Secondary Licenses”, as defined by + the Mozilla Public License, v. 2.0. diff --git a/kubernetes-vault/vault/Makefile b/kubernetes-vault/vault/Makefile new file mode 100644 index 0000000..466ef5f --- /dev/null +++ b/kubernetes-vault/vault/Makefile @@ -0,0 +1,101 @@ +TEST_IMAGE?=vault-helm-test +GOOGLE_CREDENTIALS?=vault-helm-test.json +CLOUDSDK_CORE_PROJECT?=vault-helm-dev-246514 +# set to run a single test - e.g acceptance/server-ha-enterprise-dr.bats +ACCEPTANCE_TESTS?=acceptance + +# filter bats unit tests to run. +UNIT_TESTS_FILTER?='.*' + +# set to 'true' to run acceptance tests locally in a kind cluster +LOCAL_ACCEPTANCE_TESTS?=false + +# kind cluster name +KIND_CLUSTER_NAME?=vault-helm + +# kind k8s version +KIND_K8S_VERSION?=v1.30.0 + +# Generate json schema for chart values. See test/README.md for more details. +values-schema: + helm schema-gen values.yaml > values.schema.json + +test-image: + @docker build --rm -t $(TEST_IMAGE) -f $(CURDIR)/test/docker/Test.dockerfile $(CURDIR) + +test-unit: + @docker run --rm -it -v ${PWD}:/helm-test $(TEST_IMAGE) bats -f $(UNIT_TESTS_FILTER) /helm-test/test/unit + +test-bats: test-unit test-acceptance + +test: test-image test-bats + +# run acceptance tests on GKE +# set google project/credential vars above +test-acceptance: +ifeq ($(LOCAL_ACCEPTANCE_TESTS),true) + make setup-kind acceptance +else + @docker run -it -v ${PWD}:/helm-test \ + -e GOOGLE_CREDENTIALS=${GOOGLE_CREDENTIALS} \ + -e CLOUDSDK_CORE_PROJECT=${CLOUDSDK_CORE_PROJECT} \ + -e KUBECONFIG=/helm-test/.kube/config \ + -e VAULT_LICENSE_CI=${VAULT_LICENSE_CI} \ + -w /helm-test \ + $(TEST_IMAGE) \ + make acceptance +endif + +# destroy GKE cluster using terraform +test-destroy: + @docker run -it -v ${PWD}:/helm-test \ + -e GOOGLE_CREDENTIALS=${GOOGLE_CREDENTIALS} \ + -e CLOUDSDK_CORE_PROJECT=${CLOUDSDK_CORE_PROJECT} \ + -w /helm-test \ + $(TEST_IMAGE) \ + make destroy-cluster + +# provision GKE cluster using terraform +test-provision: + @docker run -it -v ${PWD}:/helm-test \ + -e GOOGLE_CREDENTIALS=${GOOGLE_CREDENTIALS} \ + -e CLOUDSDK_CORE_PROJECT=${CLOUDSDK_CORE_PROJECT} \ + -e KUBECONFIG=/helm-test/.kube/config \ + -w /helm-test \ + $(TEST_IMAGE) \ + make provision-cluster + +# this target is for running the acceptance tests +# it is run in the docker container above when the test-acceptance target is invoked +acceptance: +ifneq ($(LOCAL_ACCEPTANCE_TESTS),true) + gcloud auth activate-service-account --key-file=${GOOGLE_CREDENTIALS} +endif + bats --tap --timing test/${ACCEPTANCE_TESTS} + +# this target is for provisioning the GKE cluster +# it is run in the docker container above when the test-provision target is invoked +provision-cluster: + gcloud auth activate-service-account --key-file=${GOOGLE_CREDENTIALS} + terraform init test/terraform + terraform apply -var project=${CLOUDSDK_CORE_PROJECT} -var init_cli=true -auto-approve test/terraform + +# this target is for removing the GKE cluster +# it is run in the docker container above when the test-destroy target is invoked +destroy-cluster: + terraform destroy -auto-approve + +# create a kind cluster for running the acceptance tests locally +setup-kind: + kind get clusters | grep -q "^${KIND_CLUSTER_NAME}$$" || \ + kind create cluster \ + --image kindest/node:${KIND_K8S_VERSION} \ + --name ${KIND_CLUSTER_NAME} \ + --config $(CURDIR)/test/kind/config.yaml + kubectl config use-context kind-${KIND_CLUSTER_NAME} + +# delete the kind cluster +delete-kind: + kind delete cluster --name ${KIND_CLUSTER_NAME} || : + +.PHONY: values-schema test-image test-unit test-bats test test-acceptance test-destroy test-provision acceptance provision-cluster destroy-cluster diff --git a/kubernetes-vault/vault/README.md b/kubernetes-vault/vault/README.md new file mode 100644 index 0000000..18eaf88 --- /dev/null +++ b/kubernetes-vault/vault/README.md @@ -0,0 +1,43 @@ +# Vault Helm Chart + +> :warning: **Please note**: We take Vault's security and our users' trust very seriously. If +you believe you have found a security issue in Vault Helm, _please responsibly disclose_ +by contacting us at [security@hashicorp.com](mailto:security@hashicorp.com). + +This repository contains the official HashiCorp Helm chart for installing +and configuring Vault on Kubernetes. This chart supports multiple use +cases of Vault on Kubernetes depending on the values provided. + +For full documentation on this Helm chart along with all the ways you can +use Vault with Kubernetes, please see the +[Vault and Kubernetes documentation](https://developer.hashicorp.com/vault/docs/platform/k8s). + +## Prerequisites + +To use the charts here, [Helm](https://helm.sh/) must be configured for your +Kubernetes cluster. Setting up Kubernetes and Helm is outside the scope of +this README. Please refer to the Kubernetes and Helm documentation. + +The versions required are: + + * **Helm 3.6+** + * **Kubernetes 1.26+** - This is the earliest version of Kubernetes tested. + It is possible that this chart works with earlier versions but it is + untested. + +## Usage + +To install the latest version of this chart, add the Hashicorp helm repository +and run `helm install`: + +```console +$ helm repo add hashicorp https://helm.releases.hashicorp.com +"hashicorp" has been added to your repositories + +$ helm install vault hashicorp/vault +``` + +Please see the many options supported in the `values.yaml` file. These are also +fully documented directly on the [Vault +website](https://developer.hashicorp.com/vault/docs/platform/k8s/helm) along with more +detailed installation instructions. diff --git a/kubernetes-vault/vault/templates/NOTES.txt b/kubernetes-vault/vault/templates/NOTES.txt new file mode 100644 index 0000000..60d99a4 --- /dev/null +++ b/kubernetes-vault/vault/templates/NOTES.txt @@ -0,0 +1,14 @@ + +Thank you for installing HashiCorp Vault! + +Now that you have deployed Vault, you should look over the docs on using +Vault with Kubernetes available here: + +https://developer.hashicorp.com/vault/docs + + +Your release is named {{ .Release.Name }}. To learn more about the release, try: + + $ helm status {{ .Release.Name }} + $ helm get manifest {{ .Release.Name }} + diff --git a/kubernetes-vault/vault/templates/_helpers.tpl b/kubernetes-vault/vault/templates/_helpers.tpl new file mode 100644 index 0000000..7a22d04 --- /dev/null +++ b/kubernetes-vault/vault/templates/_helpers.tpl @@ -0,0 +1,1105 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{/* +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 "vault.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "vault.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Expand the name of the chart. +*/}} +{{- define "vault.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Allow the release namespace to be overridden +*/}} +{{- define "vault.namespace" -}} +{{- default .Release.Namespace .Values.global.namespace -}} +{{- end -}} + +{{/* +Compute if the csi driver is enabled. +*/}} +{{- define "vault.csiEnabled" -}} +{{- $_ := set . "csiEnabled" (or + (eq (.Values.csi.enabled | toString) "true") + (and (eq (.Values.csi.enabled | toString) "-") (eq (.Values.global.enabled | toString) "true"))) -}} +{{- end -}} + +{{/* +Compute if the injector is enabled. +*/}} +{{- define "vault.injectorEnabled" -}} +{{- $_ := set . "injectorEnabled" (or + (eq (.Values.injector.enabled | toString) "true") + (and (eq (.Values.injector.enabled | toString) "-") (eq (.Values.global.enabled | toString) "true"))) -}} +{{- end -}} + +{{/* +Compute if the server is enabled. +*/}} +{{- define "vault.serverEnabled" -}} +{{- $_ := set . "serverEnabled" (or + (eq (.Values.server.enabled | toString) "true") + (and (eq (.Values.server.enabled | toString) "-") (eq (.Values.global.enabled | toString) "true"))) -}} +{{- end -}} + +{{/* +Compute if the server serviceaccount is enabled. +*/}} +{{- define "vault.serverServiceAccountEnabled" -}} +{{- $_ := set . "serverServiceAccountEnabled" + (and + (eq (.Values.server.serviceAccount.create | toString) "true" ) + (or + (eq (.Values.server.enabled | toString) "true") + (eq (.Values.global.enabled | toString) "true"))) -}} +{{- end -}} + +{{/* +Compute if the server serviceaccount should have a token created and mounted to the serviceaccount. +*/}} +{{- define "vault.serverServiceAccountSecretCreationEnabled" -}} +{{- $_ := set . "serverServiceAccountSecretCreationEnabled" + (and + (eq (.Values.server.serviceAccount.create | toString) "true") + (eq (.Values.server.serviceAccount.createSecret | toString) "true")) -}} +{{- end -}} + + +{{/* +Compute if the server auth delegator serviceaccount is enabled. +*/}} +{{- define "vault.serverAuthDelegator" -}} +{{- $_ := set . "serverAuthDelegator" + (and + (eq (.Values.server.authDelegator.enabled | toString) "true" ) + (or (eq (.Values.server.serviceAccount.create | toString) "true") + (not (eq .Values.server.serviceAccount.name ""))) + (or + (eq (.Values.server.enabled | toString) "true") + (eq (.Values.global.enabled | toString) "true"))) -}} +{{- end -}} + +{{/* +Compute if the server service is enabled. +*/}} +{{- define "vault.serverServiceEnabled" -}} +{{- template "vault.serverEnabled" . -}} +{{- $_ := set . "serverServiceEnabled" (and .serverEnabled (eq (.Values.server.service.enabled | toString) "true")) -}} +{{- end -}} + +{{/* +Compute if the ui is enabled. +*/}} +{{- define "vault.uiEnabled" -}} +{{- $_ := set . "uiEnabled" (or + (eq (.Values.ui.enabled | toString) "true") + (and (eq (.Values.ui.enabled | toString) "-") (eq (.Values.global.enabled | toString) "true"))) -}} +{{- end -}} + +{{/* +Compute the maximum number of unavailable replicas for the PodDisruptionBudget. +This defaults to (n/2)-1 where n is the number of members of the server cluster. +Add a special case for replicas=1, where it should default to 0 as well. +*/}} +{{- define "vault.pdb.maxUnavailable" -}} +{{- if eq (int .Values.server.ha.replicas) 1 -}} +{{ 0 }} +{{- else if .Values.server.ha.disruptionBudget.maxUnavailable -}} +{{ .Values.server.ha.disruptionBudget.maxUnavailable -}} +{{- else -}} +{{- div (sub (div (mul (int .Values.server.ha.replicas) 10) 2) 1) 10 -}} +{{- end -}} +{{- end -}} + +{{/* +Set the variable 'mode' to the server mode requested by the user to simplify +template logic. +*/}} +{{- define "vault.mode" -}} + {{- template "vault.serverEnabled" . -}} + {{- if or (.Values.injector.externalVaultAddr) (.Values.global.externalVaultAddr) -}} + {{- $_ := set . "mode" "external" -}} + {{- else if not .serverEnabled -}} + {{- $_ := set . "mode" "external" -}} + {{- else if eq (.Values.server.dev.enabled | toString) "true" -}} + {{- $_ := set . "mode" "dev" -}} + {{- else if eq (.Values.server.ha.enabled | toString) "true" -}} + {{- $_ := set . "mode" "ha" -}} + {{- else if or (eq (.Values.server.standalone.enabled | toString) "true") (eq (.Values.server.standalone.enabled | toString) "-") -}} + {{- $_ := set . "mode" "standalone" -}} + {{- else -}} + {{- $_ := set . "mode" "" -}} + {{- end -}} +{{- end -}} + +{{/* +Set's the replica count based on the different modes configured by user +*/}} +{{- define "vault.replicas" -}} + {{ if eq .mode "standalone" }} + {{- default 1 -}} + {{ else if eq .mode "ha" }} + {{- if or (kindIs "int64" .Values.server.ha.replicas) (kindIs "float64" .Values.server.ha.replicas) -}} + {{- .Values.server.ha.replicas -}} + {{ else }} + {{- 3 -}} + {{- end -}} + {{ else }} + {{- default 1 -}} + {{ end }} +{{- end -}} + +{{/* +Set's up configmap mounts if this isn't a dev deployment and the user +defined a custom configuration. Additionally iterates over any +extra volumes the user may have specified (such as a secret with TLS). +*/}} +{{- define "vault.volumes" -}} + {{- if and (ne .mode "dev") (or (.Values.server.standalone.config) (.Values.server.ha.config)) }} + - name: config + configMap: + name: {{ template "vault.fullname" . }}-config + {{ end }} + {{- range .Values.server.extraVolumes }} + - name: userconfig-{{ .name }} + {{ .type }}: + {{- if (eq .type "configMap") }} + name: {{ .name }} + {{- else if (eq .type "secret") }} + secretName: {{ .name }} + {{- end }} + defaultMode: {{ .defaultMode | default 420 }} + {{- end }} + {{- if .Values.server.volumes }} + {{- toYaml .Values.server.volumes | nindent 8}} + {{- end }} + {{- if (and .Values.server.enterpriseLicense.secretName .Values.server.enterpriseLicense.secretKey) }} + - name: vault-license + secret: + secretName: {{ .Values.server.enterpriseLicense.secretName }} + defaultMode: 0440 + {{- end }} +{{- end -}} + +{{/* +Set's the args for custom command to render the Vault configuration +file with IP addresses to make the out of box experience easier +for users looking to use this chart with Consul Helm. +*/}} +{{- define "vault.args" -}} + {{ if or (eq .mode "standalone") (eq .mode "ha") }} + - | + cp /vault/config/extraconfig-from-values.hcl /tmp/storageconfig.hcl; + [ -n "${HOST_IP}" ] && sed -Ei "s|HOST_IP|${HOST_IP?}|g" /tmp/storageconfig.hcl; + [ -n "${POD_IP}" ] && sed -Ei "s|POD_IP|${POD_IP?}|g" /tmp/storageconfig.hcl; + [ -n "${HOSTNAME}" ] && sed -Ei "s|HOSTNAME|${HOSTNAME?}|g" /tmp/storageconfig.hcl; + [ -n "${API_ADDR}" ] && sed -Ei "s|API_ADDR|${API_ADDR?}|g" /tmp/storageconfig.hcl; + [ -n "${TRANSIT_ADDR}" ] && sed -Ei "s|TRANSIT_ADDR|${TRANSIT_ADDR?}|g" /tmp/storageconfig.hcl; + [ -n "${RAFT_ADDR}" ] && sed -Ei "s|RAFT_ADDR|${RAFT_ADDR?}|g" /tmp/storageconfig.hcl; + /usr/local/bin/docker-entrypoint.sh vault server -config=/tmp/storageconfig.hcl {{ .Values.server.extraArgs }} + {{ else if eq .mode "dev" }} + - | + /usr/local/bin/docker-entrypoint.sh vault server -dev {{ .Values.server.extraArgs }} + {{ end }} +{{- end -}} + +{{/* +Set's additional environment variables based on the mode. +*/}} +{{- define "vault.envs" -}} + {{ if eq .mode "dev" }} + - name: VAULT_DEV_ROOT_TOKEN_ID + value: {{ .Values.server.dev.devRootToken }} + - name: VAULT_DEV_LISTEN_ADDRESS + value: "[::]:8200" + {{ end }} +{{- end -}} + +{{/* +Set's which additional volumes should be mounted to the container +based on the mode configured. +*/}} +{{- define "vault.mounts" -}} + {{ if eq (.Values.server.auditStorage.enabled | toString) "true" }} + - name: audit + mountPath: {{ .Values.server.auditStorage.mountPath }} + {{ end }} + {{ if or (eq .mode "standalone") (and (eq .mode "ha") (eq (.Values.server.ha.raft.enabled | toString) "true")) }} + {{ if eq (.Values.server.dataStorage.enabled | toString) "true" }} + - name: data + mountPath: {{ .Values.server.dataStorage.mountPath }} + {{ end }} + {{ end }} + {{ if and (ne .mode "dev") (or (.Values.server.standalone.config) (.Values.server.ha.config)) }} + - name: config + mountPath: /vault/config + {{ end }} + {{- range .Values.server.extraVolumes }} + - name: userconfig-{{ .name }} + readOnly: true + mountPath: {{ .path | default "/vault/userconfig" }}/{{ .name }} + {{- end }} + {{- if .Values.server.volumeMounts }} + {{- toYaml .Values.server.volumeMounts | nindent 12}} + {{- end }} + {{- if (and .Values.server.enterpriseLicense.secretName .Values.server.enterpriseLicense.secretKey) }} + - name: vault-license + mountPath: /vault/license + readOnly: true + {{- end }} +{{- end -}} + +{{/* +Set's up the volumeClaimTemplates when data or audit storage is required. HA +might not use data storage since Consul is likely it's backend, however, audit +storage might be desired by the user. +*/}} +{{- define "vault.volumeclaims" -}} + {{- if and (ne .mode "dev") (or .Values.server.dataStorage.enabled .Values.server.auditStorage.enabled) }} + volumeClaimTemplates: + {{- if and (eq (.Values.server.dataStorage.enabled | toString) "true") (or (eq .mode "standalone") (eq (.Values.server.ha.raft.enabled | toString ) "true" )) }} + - metadata: + name: data + {{- include "vault.dataVolumeClaim.annotations" . | nindent 6 }} + {{- include "vault.dataVolumeClaim.labels" . | nindent 6 }} + spec: + accessModes: + - {{ .Values.server.dataStorage.accessMode | default "ReadWriteOnce" }} + resources: + requests: + storage: {{ .Values.server.dataStorage.size }} + {{- if .Values.server.dataStorage.storageClass }} + storageClassName: {{ .Values.server.dataStorage.storageClass }} + {{- end }} + {{ end }} + {{- if eq (.Values.server.auditStorage.enabled | toString) "true" }} + - metadata: + name: audit + {{- include "vault.auditVolumeClaim.annotations" . | nindent 6 }} + {{- include "vault.auditVolumeClaim.labels" . | nindent 6 }} + spec: + accessModes: + - {{ .Values.server.auditStorage.accessMode | default "ReadWriteOnce" }} + resources: + requests: + storage: {{ .Values.server.auditStorage.size }} + {{- if .Values.server.auditStorage.storageClass }} + storageClassName: {{ .Values.server.auditStorage.storageClass }} + {{- end }} + {{ end }} + {{ end }} +{{- end -}} + +{{/* +Set's the affinity for pod placement when running in standalone and HA modes. +*/}} +{{- define "vault.affinity" -}} + {{- if and (ne .mode "dev") .Values.server.affinity }} + affinity: + {{ $tp := typeOf .Values.server.affinity }} + {{- if eq $tp "string" }} + {{- tpl .Values.server.affinity . | nindent 8 | trim }} + {{- else }} + {{- toYaml .Values.server.affinity | nindent 8 }} + {{- end }} + {{ end }} +{{- end -}} + +{{/* +Sets the injector affinity for pod placement +*/}} +{{- define "injector.affinity" -}} + {{- if .Values.injector.affinity }} + affinity: + {{ $tp := typeOf .Values.injector.affinity }} + {{- if eq $tp "string" }} + {{- tpl .Values.injector.affinity . | nindent 8 | trim }} + {{- else }} + {{- toYaml .Values.injector.affinity | nindent 8 }} + {{- end }} + {{ end }} +{{- end -}} + +{{/* +Sets the topologySpreadConstraints when running in standalone and HA modes. +*/}} +{{- define "vault.topologySpreadConstraints" -}} + {{- if and (ne .mode "dev") .Values.server.topologySpreadConstraints }} + topologySpreadConstraints: + {{ $tp := typeOf .Values.server.topologySpreadConstraints }} + {{- if eq $tp "string" }} + {{- tpl .Values.server.topologySpreadConstraints . | nindent 8 | trim }} + {{- else }} + {{- toYaml .Values.server.topologySpreadConstraints | nindent 8 }} + {{- end }} + {{ end }} +{{- end -}} + + +{{/* +Sets the injector topologySpreadConstraints for pod placement +*/}} +{{- define "injector.topologySpreadConstraints" -}} + {{- if .Values.injector.topologySpreadConstraints }} + topologySpreadConstraints: + {{ $tp := typeOf .Values.injector.topologySpreadConstraints }} + {{- if eq $tp "string" }} + {{- tpl .Values.injector.topologySpreadConstraints . | nindent 8 | trim }} + {{- else }} + {{- toYaml .Values.injector.topologySpreadConstraints | nindent 8 }} + {{- end }} + {{ end }} +{{- end -}} + +{{/* +Sets the toleration for pod placement when running in standalone and HA modes. +*/}} +{{- define "vault.tolerations" -}} + {{- if and (ne .mode "dev") .Values.server.tolerations }} + tolerations: + {{- $tp := typeOf .Values.server.tolerations }} + {{- if eq $tp "string" }} + {{ tpl .Values.server.tolerations . | nindent 8 | trim }} + {{- else }} + {{- toYaml .Values.server.tolerations | nindent 8 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Sets the injector toleration for pod placement +*/}} +{{- define "injector.tolerations" -}} + {{- if .Values.injector.tolerations }} + tolerations: + {{- $tp := typeOf .Values.injector.tolerations }} + {{- if eq $tp "string" }} + {{ tpl .Values.injector.tolerations . | nindent 8 | trim }} + {{- else }} + {{- toYaml .Values.injector.tolerations | nindent 8 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Set's the node selector for pod placement when running in standalone and HA modes. +*/}} +{{- define "vault.nodeselector" -}} + {{- if and (ne .mode "dev") .Values.server.nodeSelector }} + nodeSelector: + {{- $tp := typeOf .Values.server.nodeSelector }} + {{- if eq $tp "string" }} + {{ tpl .Values.server.nodeSelector . | nindent 8 | trim }} + {{- else }} + {{- toYaml .Values.server.nodeSelector | nindent 8 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Sets the injector node selector for pod placement +*/}} +{{- define "injector.nodeselector" -}} + {{- if .Values.injector.nodeSelector }} + nodeSelector: + {{- $tp := typeOf .Values.injector.nodeSelector }} + {{- if eq $tp "string" }} + {{ tpl .Values.injector.nodeSelector . | nindent 8 | trim }} + {{- else }} + {{- toYaml .Values.injector.nodeSelector | nindent 8 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Sets the injector deployment update strategy +*/}} +{{- define "injector.strategy" -}} + {{- if .Values.injector.strategy }} + strategy: + {{- $tp := typeOf .Values.injector.strategy }} + {{- if eq $tp "string" }} + {{ tpl .Values.injector.strategy . | nindent 4 | trim }} + {{- else }} + {{- toYaml .Values.injector.strategy | nindent 4 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Sets extra pod annotations +*/}} +{{- define "vault.annotations" }} + annotations: + {{- if .Values.server.includeConfigAnnotation }} + vault.hashicorp.com/config-checksum: {{ include "vault.config" . | sha256sum }} + {{- end }} + {{- if .Values.server.annotations }} + {{- $tp := typeOf .Values.server.annotations }} + {{- if eq $tp "string" }} + {{- tpl .Values.server.annotations . | nindent 8 }} + {{- else }} + {{- toYaml .Values.server.annotations | nindent 8 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Sets extra injector pod annotations +*/}} +{{- define "injector.annotations" -}} + {{- if .Values.injector.annotations }} + annotations: + {{- $tp := typeOf .Values.injector.annotations }} + {{- if eq $tp "string" }} + {{- tpl .Values.injector.annotations . | nindent 8 }} + {{- else }} + {{- toYaml .Values.injector.annotations | nindent 8 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Sets extra injector service annotations +*/}} +{{- define "injector.service.annotations" -}} + {{- if .Values.injector.service.annotations }} + annotations: + {{- $tp := typeOf .Values.injector.service.annotations }} + {{- if eq $tp "string" }} + {{- tpl .Values.injector.service.annotations . | nindent 4 }} + {{- else }} + {{- toYaml .Values.injector.service.annotations | nindent 4 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +securityContext for the injector pod level. +*/}} +{{- define "injector.securityContext.pod" -}} + {{- if .Values.injector.securityContext.pod }} + securityContext: + {{- $tp := typeOf .Values.injector.securityContext.pod }} + {{- if eq $tp "string" }} + {{- tpl .Values.injector.securityContext.pod . | nindent 8 }} + {{- else }} + {{- toYaml .Values.injector.securityContext.pod | nindent 8 }} + {{- end }} + {{- else if not .Values.global.openshift }} + securityContext: + runAsNonRoot: true + runAsGroup: {{ .Values.injector.gid | default 1000 }} + runAsUser: {{ .Values.injector.uid | default 100 }} + fsGroup: {{ .Values.injector.gid | default 1000 }} + {{- end }} +{{- end -}} + +{{/* +securityContext for the injector container level. +*/}} +{{- define "injector.securityContext.container" -}} + {{- if .Values.injector.securityContext.container}} + securityContext: + {{- $tp := typeOf .Values.injector.securityContext.container }} + {{- if eq $tp "string" }} + {{- tpl .Values.injector.securityContext.container . | nindent 12 }} + {{- else }} + {{- toYaml .Values.injector.securityContext.container | nindent 12 }} + {{- end }} + {{- else if not .Values.global.openshift }} + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + {{- end }} +{{- end -}} + +{{/* +securityContext for the statefulset pod template. +*/}} +{{- define "server.statefulSet.securityContext.pod" -}} + {{- if .Values.server.statefulSet.securityContext.pod }} + securityContext: + {{- $tp := typeOf .Values.server.statefulSet.securityContext.pod }} + {{- if eq $tp "string" }} + {{- tpl .Values.server.statefulSet.securityContext.pod . | nindent 8 }} + {{- else }} + {{- toYaml .Values.server.statefulSet.securityContext.pod | nindent 8 }} + {{- end }} + {{- else if not .Values.global.openshift }} + securityContext: + runAsNonRoot: true + runAsGroup: {{ .Values.server.gid | default 1000 }} + runAsUser: {{ .Values.server.uid | default 100 }} + fsGroup: {{ .Values.server.gid | default 1000 }} + {{- end }} +{{- end -}} + +{{/* +securityContext for the statefulset vault container +*/}} +{{- define "server.statefulSet.securityContext.container" -}} + {{- if .Values.server.statefulSet.securityContext.container }} + securityContext: + {{- $tp := typeOf .Values.server.statefulSet.securityContext.container }} + {{- if eq $tp "string" }} + {{- tpl .Values.server.statefulSet.securityContext.container . | nindent 12 }} + {{- else }} + {{- toYaml .Values.server.statefulSet.securityContext.container | nindent 12 }} + {{- end }} + {{- else if not .Values.global.openshift }} + securityContext: + allowPrivilegeEscalation: false + {{- end }} +{{- end -}} + + +{{/* +Sets extra injector service account annotations +*/}} +{{- define "injector.serviceAccount.annotations" -}} + {{- if and (ne .mode "dev") .Values.injector.serviceAccount.annotations }} + annotations: + {{- $tp := typeOf .Values.injector.serviceAccount.annotations }} + {{- if eq $tp "string" }} + {{- tpl .Values.injector.serviceAccount.annotations . | nindent 4 }} + {{- else }} + {{- toYaml .Values.injector.serviceAccount.annotations | nindent 4 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Sets extra injector webhook annotations +*/}} +{{- define "injector.webhookAnnotations" -}} + {{- if or (((.Values.injector.webhook)).annotations) (.Values.injector.webhookAnnotations) }} + annotations: + {{- $tp := typeOf (or (((.Values.injector.webhook)).annotations) (.Values.injector.webhookAnnotations)) }} + {{- if eq $tp "string" }} + {{- tpl (((.Values.injector.webhook)).annotations | default .Values.injector.webhookAnnotations) . | nindent 4 }} + {{- else }} + {{- toYaml (((.Values.injector.webhook)).annotations | default .Values.injector.webhookAnnotations) | nindent 4 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Set's the injector webhook objectSelector +*/}} +{{- define "injector.objectSelector" -}} + {{- $v := or (((.Values.injector.webhook)).objectSelector) (.Values.injector.objectSelector) -}} + {{ if $v }} + objectSelector: + {{- $tp := typeOf $v -}} + {{ if eq $tp "string" }} + {{ tpl $v . | indent 6 | trim }} + {{ else }} + {{ toYaml $v | indent 6 | trim }} + {{ end }} + {{ end }} +{{ end }} + +{{/* +Sets extra ui service annotations +*/}} +{{- define "vault.ui.annotations" -}} + {{- if .Values.ui.annotations }} + annotations: + {{- $tp := typeOf .Values.ui.annotations }} + {{- if eq $tp "string" }} + {{- tpl .Values.ui.annotations . | nindent 4 }} + {{- else }} + {{- toYaml .Values.ui.annotations | nindent 4 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "vault.serviceAccount.name" -}} +{{- if .Values.server.serviceAccount.create -}} + {{ default (include "vault.fullname" .) .Values.server.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.server.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Sets extra service account annotations +*/}} +{{- define "vault.serviceAccount.annotations" -}} + {{- if and (ne .mode "dev") .Values.server.serviceAccount.annotations }} + annotations: + {{- $tp := typeOf .Values.server.serviceAccount.annotations }} + {{- if eq $tp "string" }} + {{- tpl .Values.server.serviceAccount.annotations . | nindent 4 }} + {{- else }} + {{- toYaml .Values.server.serviceAccount.annotations | nindent 4 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Sets extra ingress annotations +*/}} +{{- define "vault.ingress.annotations" -}} + {{- if .Values.server.ingress.annotations }} + annotations: + {{- $tp := typeOf .Values.server.ingress.annotations }} + {{- if eq $tp "string" }} + {{- tpl .Values.server.ingress.annotations . | nindent 4 }} + {{- else }} + {{- toYaml .Values.server.ingress.annotations | nindent 4 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Sets extra route annotations +*/}} +{{- define "vault.route.annotations" -}} + {{- if .Values.server.route.annotations }} + annotations: + {{- $tp := typeOf .Values.server.route.annotations }} + {{- if eq $tp "string" }} + {{- tpl .Values.server.route.annotations . | nindent 4 }} + {{- else }} + {{- toYaml .Values.server.route.annotations | nindent 4 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Sets extra vault server Service annotations +*/}} +{{- define "vault.service.annotations" -}} + {{- if .Values.server.service.annotations }} + {{- $tp := typeOf .Values.server.service.annotations }} + {{- if eq $tp "string" }} + {{- tpl .Values.server.service.annotations . | nindent 4 }} + {{- else }} + {{- toYaml .Values.server.service.annotations | nindent 4 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Sets extra vault server Service (active) annotations +*/}} +{{- define "vault.service.active.annotations" -}} + {{- if .Values.server.service.active.annotations }} + {{- $tp := typeOf .Values.server.service.active.annotations }} + {{- if eq $tp "string" }} + {{- tpl .Values.server.service.active.annotations . | nindent 4 }} + {{- else }} + {{- toYaml .Values.server.service.active.annotations | nindent 4 }} + {{- end }} + {{- end }} +{{- end -}} +{{/* +Sets extra vault server Service annotations +*/}} +{{- define "vault.service.standby.annotations" -}} + {{- if .Values.server.service.standby.annotations }} + {{- $tp := typeOf .Values.server.service.standby.annotations }} + {{- if eq $tp "string" }} + {{- tpl .Values.server.service.standby.annotations . | nindent 4 }} + {{- else }} + {{- toYaml .Values.server.service.standby.annotations | nindent 4 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Sets PodSecurityPolicy annotations +*/}} +{{- define "vault.psp.annotations" -}} + {{- if .Values.global.psp.annotations }} + annotations: + {{- $tp := typeOf .Values.global.psp.annotations }} + {{- if eq $tp "string" }} + {{- tpl .Values.global.psp.annotations . | nindent 4 }} + {{- else }} + {{- toYaml .Values.global.psp.annotations | nindent 4 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Sets extra statefulset annotations +*/}} +{{- define "vault.statefulSet.annotations" -}} + {{- if .Values.server.statefulSet.annotations }} + annotations: + {{- $tp := typeOf .Values.server.statefulSet.annotations }} + {{- if eq $tp "string" }} + {{- tpl .Values.server.statefulSet.annotations . | nindent 4 }} + {{- else }} + {{- toYaml .Values.server.statefulSet.annotations | nindent 4 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Sets VolumeClaim annotations for data volume +*/}} +{{- define "vault.dataVolumeClaim.annotations" -}} + {{- if and (ne .mode "dev") (.Values.server.dataStorage.enabled) (.Values.server.dataStorage.annotations) }} + annotations: + {{- $tp := typeOf .Values.server.dataStorage.annotations }} + {{- if eq $tp "string" }} + {{- tpl .Values.server.dataStorage.annotations . | nindent 4 }} + {{- else }} + {{- toYaml .Values.server.dataStorage.annotations | nindent 4 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Sets VolumeClaim labels for data volume +*/}} +{{- define "vault.dataVolumeClaim.labels" -}} + {{- if and (ne .mode "dev") (.Values.server.dataStorage.enabled) (.Values.server.dataStorage.labels) }} + labels: + {{- $tp := typeOf .Values.server.dataStorage.labels }} + {{- if eq $tp "string" }} + {{- tpl .Values.server.dataStorage.labels . | nindent 4 }} + {{- else }} + {{- toYaml .Values.server.dataStorage.labels | nindent 4 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Sets VolumeClaim annotations for audit volume +*/}} +{{- define "vault.auditVolumeClaim.annotations" -}} + {{- if and (ne .mode "dev") (.Values.server.auditStorage.enabled) (.Values.server.auditStorage.annotations) }} + annotations: + {{- $tp := typeOf .Values.server.auditStorage.annotations }} + {{- if eq $tp "string" }} + {{- tpl .Values.server.auditStorage.annotations . | nindent 4 }} + {{- else }} + {{- toYaml .Values.server.auditStorage.annotations | nindent 4 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Sets VolumeClaim labels for audit volume +*/}} +{{- define "vault.auditVolumeClaim.labels" -}} + {{- if and (ne .mode "dev") (.Values.server.auditStorage.enabled) (.Values.server.auditStorage.labels) }} + labels: + {{- $tp := typeOf .Values.server.auditStorage.labels }} + {{- if eq $tp "string" }} + {{- tpl .Values.server.auditStorage.labels . | nindent 4 }} + {{- else }} + {{- toYaml .Values.server.auditStorage.labels | nindent 4 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Set's the container resources if the user has set any. +*/}} +{{- define "vault.resources" -}} + {{- if .Values.server.resources -}} + resources: +{{ toYaml .Values.server.resources | indent 12}} + {{ end }} +{{- end -}} + +{{/* +Sets the container resources if the user has set any. +*/}} +{{- define "injector.resources" -}} + {{- if .Values.injector.resources -}} + resources: +{{ toYaml .Values.injector.resources | indent 12}} + {{ end }} +{{- end -}} + +{{/* +Sets the container resources if the user has set any. +*/}} +{{- define "csi.resources" -}} + {{- if .Values.csi.resources -}} + resources: +{{ toYaml .Values.csi.resources | indent 12}} + {{ end }} +{{- end -}} + +{{/* +Sets the container resources for CSI's Agent sidecar if the user has set any. +*/}} +{{- define "csi.agent.resources" -}} + {{- if .Values.csi.agent.resources -}} + resources: +{{ toYaml .Values.csi.agent.resources | indent 12}} + {{ end }} +{{- end -}} + +{{/* +Sets extra CSI daemonset annotations +*/}} +{{- define "csi.daemonSet.annotations" -}} + {{- if .Values.csi.daemonSet.annotations }} + annotations: + {{- $tp := typeOf .Values.csi.daemonSet.annotations }} + {{- if eq $tp "string" }} + {{- tpl .Values.csi.daemonSet.annotations . | nindent 4 }} + {{- else }} + {{- toYaml .Values.csi.daemonSet.annotations | nindent 4 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Sets CSI daemonset securityContext for pod template +*/}} +{{- define "csi.daemonSet.securityContext.pod" -}} + {{- if .Values.csi.daemonSet.securityContext.pod }} + securityContext: + {{- $tp := typeOf .Values.csi.daemonSet.securityContext.pod }} + {{- if eq $tp "string" }} + {{- tpl .Values.csi.daemonSet.securityContext.pod . | nindent 8 }} + {{- else }} + {{- toYaml .Values.csi.daemonSet.securityContext.pod | nindent 8 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Sets CSI daemonset securityContext for container +*/}} +{{- define "csi.daemonSet.securityContext.container" -}} + {{- if .Values.csi.daemonSet.securityContext.container }} + securityContext: + {{- $tp := typeOf .Values.csi.daemonSet.securityContext.container }} + {{- if eq $tp "string" }} + {{- tpl .Values.csi.daemonSet.securityContext.container . | nindent 12 }} + {{- else }} + {{- toYaml .Values.csi.daemonSet.securityContext.container | nindent 12 }} + {{- end }} + {{- end }} +{{- end -}} + + +{{/* +Sets the injector toleration for pod placement +*/}} +{{- define "csi.pod.tolerations" -}} + {{- if .Values.csi.pod.tolerations }} + tolerations: + {{- $tp := typeOf .Values.csi.pod.tolerations }} + {{- if eq $tp "string" }} + {{ tpl .Values.csi.pod.tolerations . | nindent 8 | trim }} + {{- else }} + {{- toYaml .Values.csi.pod.tolerations | nindent 8 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Sets the CSI provider nodeSelector for pod placement +*/}} +{{- define "csi.pod.nodeselector" -}} + {{- if .Values.csi.pod.nodeSelector }} + nodeSelector: + {{- $tp := typeOf .Values.csi.pod.nodeSelector }} + {{- if eq $tp "string" }} + {{ tpl .Values.csi.pod.nodeSelector . | nindent 8 | trim }} + {{- else }} + {{- toYaml .Values.csi.pod.nodeSelector | nindent 8 }} + {{- end }} + {{- end }} +{{- end -}} +{{/* +Sets the CSI provider affinity for pod placement. +*/}} +{{- define "csi.pod.affinity" -}} + {{- if .Values.csi.pod.affinity }} + affinity: + {{ $tp := typeOf .Values.csi.pod.affinity }} + {{- if eq $tp "string" }} + {{- tpl .Values.csi.pod.affinity . | nindent 8 | trim }} + {{- else }} + {{- toYaml .Values.csi.pod.affinity | nindent 8 }} + {{- end }} + {{ end }} +{{- end -}} +{{/* +Sets extra CSI provider pod annotations +*/}} +{{- define "csi.pod.annotations" -}} + {{- if .Values.csi.pod.annotations }} + annotations: + {{- $tp := typeOf .Values.csi.pod.annotations }} + {{- if eq $tp "string" }} + {{- tpl .Values.csi.pod.annotations . | nindent 8 }} + {{- else }} + {{- toYaml .Values.csi.pod.annotations | nindent 8 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Sets extra CSI service account annotations +*/}} +{{- define "csi.serviceAccount.annotations" -}} + {{- if .Values.csi.serviceAccount.annotations }} + annotations: + {{- $tp := typeOf .Values.csi.serviceAccount.annotations }} + {{- if eq $tp "string" }} + {{- tpl .Values.csi.serviceAccount.annotations . | nindent 4 }} + {{- else }} + {{- toYaml .Values.csi.serviceAccount.annotations | nindent 4 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Inject extra environment vars in the format key:value, if populated +*/}} +{{- define "vault.extraEnvironmentVars" -}} +{{- if .extraEnvironmentVars -}} +{{- range $key, $value := .extraEnvironmentVars }} +- name: {{ printf "%s" $key | replace "." "_" | upper | quote }} + value: {{ $value | quote }} +{{- end }} +{{- end -}} +{{- end -}} + +{{/* +Inject extra environment populated by secrets, if populated +*/}} +{{- define "vault.extraSecretEnvironmentVars" -}} +{{- if .extraSecretEnvironmentVars -}} +{{- range .extraSecretEnvironmentVars }} +- name: {{ .envName }} + valueFrom: + secretKeyRef: + name: {{ .secretName }} + key: {{ .secretKey }} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* Scheme for health check and local endpoint */}} +{{- define "vault.scheme" -}} +{{- if .Values.global.tlsDisable -}} +{{ "http" }} +{{- else -}} +{{ "https" }} +{{- end -}} +{{- end -}} + +{{/* +imagePullSecrets generates pull secrets from either string or map values. +A map value must be indexable by the key 'name'. +*/}} +{{- define "imagePullSecrets" -}} +{{- with .Values.global.imagePullSecrets -}} +imagePullSecrets: +{{- range . -}} +{{- if typeIs "string" . }} + - name: {{ . }} +{{- else if index . "name" }} + - name: {{ .name }} +{{- end }} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +externalTrafficPolicy sets a Service's externalTrafficPolicy if applicable. +Supported inputs are Values.server.service and Values.ui +*/}} +{{- define "service.externalTrafficPolicy" -}} +{{- $type := "" -}} +{{- if .serviceType -}} +{{- $type = .serviceType -}} +{{- else if .type -}} +{{- $type = .type -}} +{{- end -}} +{{- if and .externalTrafficPolicy (or (eq $type "LoadBalancer") (eq $type "NodePort")) }} + externalTrafficPolicy: {{ .externalTrafficPolicy }} +{{- else }} +{{- end }} +{{- end -}} + +{{/* +loadBalancer configuration for the the UI service. +Supported inputs are Values.ui +*/}} +{{- define "service.loadBalancer" -}} +{{- if eq (.serviceType | toString) "LoadBalancer" }} +{{- if .loadBalancerIP }} + loadBalancerIP: {{ .loadBalancerIP }} +{{- end }} +{{- with .loadBalancerSourceRanges }} + loadBalancerSourceRanges: +{{- range . }} + - {{ . }} +{{- end }} +{{- end -}} +{{- end }} +{{- end -}} + +{{/* +config file from values +*/}} +{{- define "vault.config" -}} + {{- if or (eq .mode "ha") (eq .mode "standalone") }} + {{- $type := typeOf (index .Values.server .mode).config }} + {{- if eq $type "string" }} + disable_mlock = true + {{- if eq .mode "standalone" }} + {{ tpl .Values.server.standalone.config . | nindent 4 | trim }} + {{- else if and (eq .mode "ha") (eq (.Values.server.ha.raft.enabled | toString) "false") }} + {{ tpl .Values.server.ha.config . | nindent 4 | trim }} + {{- else if and (eq .mode "ha") (eq (.Values.server.ha.raft.enabled | toString) "true") }} + {{ tpl .Values.server.ha.raft.config . | nindent 4 | trim }} + {{ end }} + {{- else }} + {{- if and (eq .mode "ha") (eq (.Values.server.ha.raft.enabled | toString) "true") }} +{{ merge (dict "disable_mlock" true) (index .Values.server .mode).raft.config | toPrettyJson | indent 4 }} + {{- else }} +{{ merge (dict "disable_mlock" true) (index .Values.server .mode).config | toPrettyJson | indent 4 }} + {{- end }} + {{- end }} + {{- end }} +{{- end -}} \ No newline at end of file diff --git a/kubernetes-vault/vault/templates/csi-agent-configmap.yaml b/kubernetes-vault/vault/templates/csi-agent-configmap.yaml new file mode 100644 index 0000000..18cdb04 --- /dev/null +++ b/kubernetes-vault/vault/templates/csi-agent-configmap.yaml @@ -0,0 +1,34 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- template "vault.csiEnabled" . -}} +{{- if and (.csiEnabled) (eq (.Values.csi.agent.enabled | toString) "true") -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "vault.fullname" . }}-csi-provider-agent-config + namespace: {{ include "vault.namespace" . }} + labels: + helm.sh/chart: {{ include "vault.chart" . }} + app.kubernetes.io/name: {{ include "vault.name" . }}-csi-provider + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +data: + config.hcl: | + vault { + {{- if .Values.global.externalVaultAddr }} + "address" = "{{ .Values.global.externalVaultAddr }}" + {{- else }} + "address" = "{{ include "vault.scheme" . }}://{{ template "vault.fullname" . }}.{{ include "vault.namespace" . }}.svc:{{ .Values.server.service.port }}" + {{- end }} + } + + cache {} + + listener "unix" { + address = "/var/run/vault/agent.sock" + tls_disable = true + } +{{- end }} diff --git a/kubernetes-vault/vault/templates/csi-clusterrole.yaml b/kubernetes-vault/vault/templates/csi-clusterrole.yaml new file mode 100644 index 0000000..6d979ea --- /dev/null +++ b/kubernetes-vault/vault/templates/csi-clusterrole.yaml @@ -0,0 +1,23 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- template "vault.csiEnabled" . -}} +{{- if .csiEnabled -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "vault.fullname" . }}-csi-provider-clusterrole + labels: + app.kubernetes.io/name: {{ include "vault.name" . }}-csi-provider + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +rules: +- apiGroups: + - "" + resources: + - serviceaccounts/token + verbs: + - create +{{- end }} diff --git a/kubernetes-vault/vault/templates/csi-clusterrolebinding.yaml b/kubernetes-vault/vault/templates/csi-clusterrolebinding.yaml new file mode 100644 index 0000000..506ec94 --- /dev/null +++ b/kubernetes-vault/vault/templates/csi-clusterrolebinding.yaml @@ -0,0 +1,24 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- template "vault.csiEnabled" . -}} +{{- if .csiEnabled -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "vault.fullname" . }}-csi-provider-clusterrolebinding + labels: + app.kubernetes.io/name: {{ include "vault.name" . }}-csi-provider + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "vault.fullname" . }}-csi-provider-clusterrole +subjects: +- kind: ServiceAccount + name: {{ template "vault.fullname" . }}-csi-provider + namespace: {{ include "vault.namespace" . }} +{{- end }} diff --git a/kubernetes-vault/vault/templates/csi-daemonset.yaml b/kubernetes-vault/vault/templates/csi-daemonset.yaml new file mode 100644 index 0000000..1436ff9 --- /dev/null +++ b/kubernetes-vault/vault/templates/csi-daemonset.yaml @@ -0,0 +1,157 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- template "vault.csiEnabled" . -}} +{{- if .csiEnabled -}} +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ template "vault.fullname" . }}-csi-provider + namespace: {{ include "vault.namespace" . }} + labels: + app.kubernetes.io/name: {{ include "vault.name" . }}-csi-provider + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + {{- if .Values.csi.daemonSet.extraLabels -}} + {{- toYaml .Values.csi.daemonSet.extraLabels | nindent 4 -}} + {{- end -}} + {{ template "csi.daemonSet.annotations" . }} +spec: + updateStrategy: + type: {{ .Values.csi.daemonSet.updateStrategy.type }} + {{- if .Values.csi.daemonSet.updateStrategy.maxUnavailable }} + rollingUpdate: + maxUnavailable: {{ .Values.csi.daemonSet.updateStrategy.maxUnavailable }} + {{- end }} + selector: + matchLabels: + app.kubernetes.io/name: {{ include "vault.name" . }}-csi-provider + app.kubernetes.io/instance: {{ .Release.Name }} + template: + metadata: + labels: + app.kubernetes.io/name: {{ template "vault.name" . }}-csi-provider + app.kubernetes.io/instance: {{ .Release.Name }} + {{- if .Values.csi.pod.extraLabels -}} + {{- toYaml .Values.csi.pod.extraLabels | nindent 8 -}} + {{- end -}} + {{ template "csi.pod.annotations" . }} + spec: + {{ template "csi.daemonSet.securityContext.pod" . }} + {{- if .Values.csi.priorityClassName }} + priorityClassName: {{ .Values.csi.priorityClassName }} + {{- end }} + serviceAccountName: {{ template "vault.fullname" . }}-csi-provider + {{- template "csi.pod.tolerations" . }} + {{- template "csi.pod.nodeselector" . }} + {{- template "csi.pod.affinity" . }} + containers: + - name: {{ include "vault.name" . }}-csi-provider + {{ template "csi.resources" . }} + {{ template "csi.daemonSet.securityContext.container" . }} + image: "{{ .Values.csi.image.repository }}:{{ .Values.csi.image.tag }}" + imagePullPolicy: {{ .Values.csi.image.pullPolicy }} + args: + - --endpoint=/provider/vault.sock + - --debug={{ .Values.csi.debug }} + {{- if .Values.csi.hmacSecretName }} + - --hmac-secret-name={{ .Values.csi.hmacSecretName }} + {{- else }} + - --hmac-secret-name={{- include "vault.name" . }}-csi-provider-hmac-key + {{- end }} + {{- if .Values.csi.extraArgs }} + {{- toYaml .Values.csi.extraArgs | nindent 12 }} + {{- end }} + env: + - name: VAULT_ADDR + {{- if eq (.Values.csi.agent.enabled | toString) "true" }} + value: "unix:///var/run/vault/agent.sock" + {{- else if .Values.global.externalVaultAddr }} + value: "{{ .Values.global.externalVaultAddr }}" + {{- else }} + value: {{ include "vault.scheme" . }}://{{ template "vault.fullname" . }}.{{ include "vault.namespace" . }}.svc:{{ .Values.server.service.port }} + {{- end }} + volumeMounts: + - name: providervol + mountPath: "/provider" + {{- if eq (.Values.csi.agent.enabled | toString) "true" }} + - name: agent-unix-socket + mountPath: /var/run/vault + {{- end }} + {{- if .Values.csi.volumeMounts }} + {{- toYaml .Values.csi.volumeMounts | nindent 12}} + {{- end }} + livenessProbe: + httpGet: + path: /health/ready + port: 8080 + failureThreshold: {{ .Values.csi.livenessProbe.failureThreshold }} + initialDelaySeconds: {{ .Values.csi.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.csi.livenessProbe.periodSeconds }} + successThreshold: {{ .Values.csi.livenessProbe.successThreshold }} + timeoutSeconds: {{ .Values.csi.livenessProbe.timeoutSeconds }} + readinessProbe: + httpGet: + path: /health/ready + port: 8080 + failureThreshold: {{ .Values.csi.readinessProbe.failureThreshold }} + initialDelaySeconds: {{ .Values.csi.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.csi.readinessProbe.periodSeconds }} + successThreshold: {{ .Values.csi.readinessProbe.successThreshold }} + timeoutSeconds: {{ .Values.csi.readinessProbe.timeoutSeconds }} + {{- if eq (.Values.csi.agent.enabled | toString) "true" }} + - name: {{ include "vault.name" . }}-agent + image: "{{ .Values.csi.agent.image.repository }}:{{ .Values.csi.agent.image.tag }}" + imagePullPolicy: {{ .Values.csi.agent.image.pullPolicy }} + {{ template "csi.agent.resources" . }} + command: + - vault + args: + - agent + - -config=/etc/vault/config.hcl + {{- if .Values.csi.agent.extraArgs }} + {{- toYaml .Values.csi.agent.extraArgs | nindent 12 }} + {{- end }} + ports: + - containerPort: 8200 + env: + - name: VAULT_LOG_LEVEL + value: "{{ .Values.csi.agent.logLevel }}" + - name: VAULT_LOG_FORMAT + value: "{{ .Values.csi.agent.logFormat }}" + securityContext: + runAsNonRoot: true + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + runAsUser: 100 + runAsGroup: 1000 + volumeMounts: + - name: agent-config + mountPath: /etc/vault/config.hcl + subPath: config.hcl + readOnly: true + - name: agent-unix-socket + mountPath: /var/run/vault + {{- if .Values.csi.volumeMounts }} + {{- toYaml .Values.csi.volumeMounts | nindent 12 }} + {{- end }} + {{- end }} + volumes: + - name: providervol + hostPath: + path: {{ .Values.csi.daemonSet.providersDir }} + {{- if eq (.Values.csi.agent.enabled | toString) "true" }} + - name: agent-config + configMap: + name: {{ template "vault.fullname" . }}-csi-provider-agent-config + - name: agent-unix-socket + emptyDir: + medium: Memory + {{- end }} + {{- if .Values.csi.volumes }} + {{- toYaml .Values.csi.volumes | nindent 8}} + {{- end }} + {{- include "imagePullSecrets" . | nindent 6 }} +{{- end }} diff --git a/kubernetes-vault/vault/templates/csi-role.yaml b/kubernetes-vault/vault/templates/csi-role.yaml new file mode 100644 index 0000000..17e1918 --- /dev/null +++ b/kubernetes-vault/vault/templates/csi-role.yaml @@ -0,0 +1,32 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- template "vault.csiEnabled" . -}} +{{- if .csiEnabled -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "vault.fullname" . }}-csi-provider-role + namespace: {{ include "vault.namespace" . }} + labels: + app.kubernetes.io/name: {{ include "vault.name" . }}-csi-provider + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +rules: +- apiGroups: [""] + resources: ["secrets"] + verbs: ["get"] + resourceNames: + {{- if .Values.csi.hmacSecretName }} + - {{ .Values.csi.hmacSecretName }} + {{- else }} + - {{ include "vault.name" . }}-csi-provider-hmac-key + {{- end }} +# 'create' permissions cannot be restricted by resource name: +# https://kubernetes.io/docs/reference/access-authn-authz/rbac/#referring-to-resources +- apiGroups: [""] + resources: ["secrets"] + verbs: ["create"] +{{- end }} diff --git a/kubernetes-vault/vault/templates/csi-rolebinding.yaml b/kubernetes-vault/vault/templates/csi-rolebinding.yaml new file mode 100644 index 0000000..3d3b981 --- /dev/null +++ b/kubernetes-vault/vault/templates/csi-rolebinding.yaml @@ -0,0 +1,25 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- template "vault.csiEnabled" . -}} +{{- if .csiEnabled -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "vault.fullname" . }}-csi-provider-rolebinding + namespace: {{ include "vault.namespace" . }} + labels: + app.kubernetes.io/name: {{ include "vault.name" . }}-csi-provider + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "vault.fullname" . }}-csi-provider-role +subjects: +- kind: ServiceAccount + name: {{ template "vault.fullname" . }}-csi-provider + namespace: {{ include "vault.namespace" . }} +{{- end }} diff --git a/kubernetes-vault/vault/templates/csi-serviceaccount.yaml b/kubernetes-vault/vault/templates/csi-serviceaccount.yaml new file mode 100644 index 0000000..6327a7b --- /dev/null +++ b/kubernetes-vault/vault/templates/csi-serviceaccount.yaml @@ -0,0 +1,21 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- template "vault.csiEnabled" . -}} +{{- if .csiEnabled -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "vault.fullname" . }}-csi-provider + namespace: {{ include "vault.namespace" . }} + labels: + app.kubernetes.io/name: {{ include "vault.name" . }}-csi-provider + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + {{- if .Values.csi.serviceAccount.extraLabels -}} + {{- toYaml .Values.csi.serviceAccount.extraLabels | nindent 4 -}} + {{- end -}} + {{ template "csi.serviceAccount.annotations" . }} +{{- end }} diff --git a/kubernetes-vault/vault/templates/injector-certs-secret.yaml b/kubernetes-vault/vault/templates/injector-certs-secret.yaml new file mode 100644 index 0000000..f6995af --- /dev/null +++ b/kubernetes-vault/vault/templates/injector-certs-secret.yaml @@ -0,0 +1,19 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- template "vault.injectorEnabled" . -}} +{{- if .injectorEnabled -}} +{{- if and (eq (.Values.injector.leaderElector.enabled | toString) "true") (gt (.Values.injector.replicas | int) 1) }} +apiVersion: v1 +kind: Secret +metadata: + name: vault-injector-certs + namespace: {{ include "vault.namespace" . }} + labels: + app.kubernetes.io/name: {{ include "vault.name" . }}-agent-injector + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/kubernetes-vault/vault/templates/injector-clusterrole.yaml b/kubernetes-vault/vault/templates/injector-clusterrole.yaml new file mode 100644 index 0000000..df603f2 --- /dev/null +++ b/kubernetes-vault/vault/templates/injector-clusterrole.yaml @@ -0,0 +1,30 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- template "vault.injectorEnabled" . -}} +{{- if .injectorEnabled -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "vault.fullname" . }}-agent-injector-clusterrole + labels: + app.kubernetes.io/name: {{ include "vault.name" . }}-agent-injector + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +rules: +- apiGroups: ["admissionregistration.k8s.io"] + resources: ["mutatingwebhookconfigurations"] + verbs: + - "get" + - "list" + - "watch" + - "patch" +{{- if and (eq (.Values.injector.leaderElector.enabled | toString) "true") (gt (.Values.injector.replicas | int) 1) }} +- apiGroups: [""] + resources: ["nodes"] + verbs: + - "get" +{{ end }} +{{ end }} diff --git a/kubernetes-vault/vault/templates/injector-clusterrolebinding.yaml b/kubernetes-vault/vault/templates/injector-clusterrolebinding.yaml new file mode 100644 index 0000000..82cbce0 --- /dev/null +++ b/kubernetes-vault/vault/templates/injector-clusterrolebinding.yaml @@ -0,0 +1,24 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- template "vault.injectorEnabled" . -}} +{{- if .injectorEnabled -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "vault.fullname" . }}-agent-injector-binding + labels: + app.kubernetes.io/name: {{ include "vault.name" . }}-agent-injector + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "vault.fullname" . }}-agent-injector-clusterrole +subjects: +- kind: ServiceAccount + name: {{ template "vault.fullname" . }}-agent-injector + namespace: {{ include "vault.namespace" . }} +{{ end }} diff --git a/kubernetes-vault/vault/templates/injector-deployment.yaml b/kubernetes-vault/vault/templates/injector-deployment.yaml new file mode 100644 index 0000000..822e8e4 --- /dev/null +++ b/kubernetes-vault/vault/templates/injector-deployment.yaml @@ -0,0 +1,179 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- template "vault.injectorEnabled" . -}} +{{- if .injectorEnabled -}} +# Deployment for the injector +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "vault.fullname" . }}-agent-injector + namespace: {{ include "vault.namespace" . }} + labels: + app.kubernetes.io/name: {{ include "vault.name" . }}-agent-injector + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + component: webhook +spec: + replicas: {{ .Values.injector.replicas }} + selector: + matchLabels: + app.kubernetes.io/name: {{ template "vault.name" . }}-agent-injector + app.kubernetes.io/instance: {{ .Release.Name }} + component: webhook + {{ template "injector.strategy" . }} + template: + metadata: + labels: + app.kubernetes.io/name: {{ template "vault.name" . }}-agent-injector + app.kubernetes.io/instance: {{ .Release.Name }} + component: webhook + {{- if .Values.injector.extraLabels -}} + {{- toYaml .Values.injector.extraLabels | nindent 8 -}} + {{- end -}} + {{ template "injector.annotations" . }} + spec: + {{ template "injector.affinity" . }} + {{ template "injector.topologySpreadConstraints" . }} + {{ template "injector.tolerations" . }} + {{ template "injector.nodeselector" . }} + {{- if .Values.injector.priorityClassName }} + priorityClassName: {{ .Values.injector.priorityClassName }} + {{- end }} + serviceAccountName: "{{ template "vault.fullname" . }}-agent-injector" + {{ template "injector.securityContext.pod" . -}} + {{- if not .Values.global.openshift }} + hostNetwork: {{ .Values.injector.hostNetwork }} + {{- end }} + containers: + - name: sidecar-injector + {{ template "injector.resources" . }} + image: "{{ .Values.injector.image.repository }}:{{ .Values.injector.image.tag }}" + imagePullPolicy: "{{ .Values.injector.image.pullPolicy }}" + {{- template "injector.securityContext.container" . }} + env: + - name: AGENT_INJECT_LISTEN + value: {{ printf ":%v" .Values.injector.port }} + - name: AGENT_INJECT_LOG_LEVEL + value: {{ .Values.injector.logLevel | default "info" }} + - name: AGENT_INJECT_VAULT_ADDR + {{- if .Values.global.externalVaultAddr }} + value: "{{ .Values.global.externalVaultAddr }}" + {{- else if .Values.injector.externalVaultAddr }} + value: "{{ .Values.injector.externalVaultAddr }}" + {{- else }} + value: {{ include "vault.scheme" . }}://{{ template "vault.fullname" . }}.{{ include "vault.namespace" . }}.svc:{{ .Values.server.service.port }} + {{- end }} + - name: AGENT_INJECT_VAULT_AUTH_PATH + value: {{ .Values.injector.authPath }} + - name: AGENT_INJECT_VAULT_IMAGE + value: "{{ .Values.injector.agentImage.repository }}:{{ .Values.injector.agentImage.tag }}" + {{- if .Values.injector.certs.secretName }} + - name: AGENT_INJECT_TLS_CERT_FILE + value: "/etc/webhook/certs/{{ .Values.injector.certs.certName }}" + - name: AGENT_INJECT_TLS_KEY_FILE + value: "/etc/webhook/certs/{{ .Values.injector.certs.keyName }}" + {{- else }} + - name: AGENT_INJECT_TLS_AUTO + value: {{ template "vault.fullname" . }}-agent-injector-cfg + - name: AGENT_INJECT_TLS_AUTO_HOSTS + value: {{ template "vault.fullname" . }}-agent-injector-svc,{{ template "vault.fullname" . }}-agent-injector-svc.{{ include "vault.namespace" . }},{{ template "vault.fullname" . }}-agent-injector-svc.{{ include "vault.namespace" . }}.svc + {{- end }} + - name: AGENT_INJECT_LOG_FORMAT + value: {{ .Values.injector.logFormat | default "standard" }} + - name: AGENT_INJECT_REVOKE_ON_SHUTDOWN + value: "{{ .Values.injector.revokeOnShutdown | default false }}" + {{- if .Values.global.openshift }} + - name: AGENT_INJECT_SET_SECURITY_CONTEXT + value: "false" + {{- end }} + {{- if .Values.injector.metrics.enabled }} + - name: AGENT_INJECT_TELEMETRY_PATH + value: "/metrics" + {{- end }} + {{- if and (eq (.Values.injector.leaderElector.enabled | toString) "true") (gt (.Values.injector.replicas | int) 1) }} + - name: AGENT_INJECT_USE_LEADER_ELECTOR + value: "true" + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{- end }} + - name: AGENT_INJECT_CPU_REQUEST + value: "{{ .Values.injector.agentDefaults.cpuRequest }}" + - name: AGENT_INJECT_CPU_LIMIT + value: "{{ .Values.injector.agentDefaults.cpuLimit }}" + - name: AGENT_INJECT_MEM_REQUEST + value: "{{ .Values.injector.agentDefaults.memRequest }}" + - name: AGENT_INJECT_MEM_LIMIT + value: "{{ .Values.injector.agentDefaults.memLimit }}" + {{- if .Values.injector.agentDefaults.ephemeralRequest }} + - name: AGENT_INJECT_EPHEMERAL_REQUEST + value: "{{ .Values.injector.agentDefaults.ephemeralRequest }}" + {{- end }} + {{- if .Values.injector.agentDefaults.ephemeralLimit }} + - name: AGENT_INJECT_EPHEMERAL_LIMIT + value: "{{ .Values.injector.agentDefaults.ephemeralLimit }}" + {{- end }} + - name: AGENT_INJECT_DEFAULT_TEMPLATE + value: "{{ .Values.injector.agentDefaults.template }}" + - name: AGENT_INJECT_TEMPLATE_CONFIG_EXIT_ON_RETRY_FAILURE + value: "{{ .Values.injector.agentDefaults.templateConfig.exitOnRetryFailure }}" + {{- if .Values.injector.agentDefaults.templateConfig.staticSecretRenderInterval }} + - name: AGENT_INJECT_TEMPLATE_STATIC_SECRET_RENDER_INTERVAL + value: "{{ .Values.injector.agentDefaults.templateConfig.staticSecretRenderInterval }}" + {{- end }} + {{- include "vault.extraEnvironmentVars" .Values.injector | nindent 12 }} + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + args: + - agent-inject + - 2>&1 + livenessProbe: + httpGet: + path: /health/ready + port: {{ .Values.injector.port }} + scheme: HTTPS + failureThreshold: {{ .Values.injector.livenessProbe.failureThreshold }} + initialDelaySeconds: {{ .Values.injector.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.injector.livenessProbe.periodSeconds }} + successThreshold: {{ .Values.injector.livenessProbe.successThreshold }} + timeoutSeconds: {{ .Values.injector.livenessProbe.timeoutSeconds }} + readinessProbe: + httpGet: + path: /health/ready + port: {{ .Values.injector.port }} + scheme: HTTPS + failureThreshold: {{ .Values.injector.readinessProbe.failureThreshold }} + initialDelaySeconds: {{ .Values.injector.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.injector.readinessProbe.periodSeconds }} + successThreshold: {{ .Values.injector.readinessProbe.successThreshold }} + timeoutSeconds: {{ .Values.injector.readinessProbe.timeoutSeconds }} + startupProbe: + httpGet: + path: /health/ready + port: {{ .Values.injector.port }} + scheme: HTTPS + failureThreshold: {{ .Values.injector.startupProbe.failureThreshold }} + initialDelaySeconds: {{ .Values.injector.startupProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.injector.startupProbe.periodSeconds }} + successThreshold: {{ .Values.injector.startupProbe.successThreshold }} + timeoutSeconds: {{ .Values.injector.startupProbe.timeoutSeconds }} +{{- if .Values.injector.certs.secretName }} + volumeMounts: + - name: webhook-certs + mountPath: /etc/webhook/certs + readOnly: true +{{- end }} +{{- if .Values.injector.certs.secretName }} + volumes: + - name: webhook-certs + secret: + secretName: "{{ .Values.injector.certs.secretName }}" +{{- end }} + {{- include "imagePullSecrets" . | nindent 6 }} +{{ end }} diff --git a/kubernetes-vault/vault/templates/injector-disruptionbudget.yaml b/kubernetes-vault/vault/templates/injector-disruptionbudget.yaml new file mode 100644 index 0000000..2b2a61c --- /dev/null +++ b/kubernetes-vault/vault/templates/injector-disruptionbudget.yaml @@ -0,0 +1,25 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- if .Values.injector.podDisruptionBudget }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ template "vault.fullname" . }}-agent-injector + namespace: {{ include "vault.namespace" . }} + labels: + helm.sh/chart: {{ include "vault.chart" . }} + app.kubernetes.io/name: {{ include "vault.name" . }}-agent-injector + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + component: webhook +spec: + selector: + matchLabels: + app.kubernetes.io/name: {{ template "vault.name" . }}-agent-injector + app.kubernetes.io/instance: {{ .Release.Name }} + component: webhook + {{- toYaml .Values.injector.podDisruptionBudget | nindent 2 }} +{{- end -}} diff --git a/kubernetes-vault/vault/templates/injector-mutating-webhook.yaml b/kubernetes-vault/vault/templates/injector-mutating-webhook.yaml new file mode 100644 index 0000000..d0cafa6 --- /dev/null +++ b/kubernetes-vault/vault/templates/injector-mutating-webhook.yaml @@ -0,0 +1,45 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- template "vault.injectorEnabled" . -}} +{{- if .injectorEnabled -}} +{{- if .Capabilities.APIVersions.Has "admissionregistration.k8s.io/v1" }} +apiVersion: admissionregistration.k8s.io/v1 +{{- else }} +apiVersion: admissionregistration.k8s.io/v1beta1 +{{- end }} +kind: MutatingWebhookConfiguration +metadata: + name: {{ template "vault.fullname" . }}-agent-injector-cfg + labels: + app.kubernetes.io/name: {{ include "vault.name" . }}-agent-injector + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + {{- template "injector.webhookAnnotations" . }} +webhooks: + - name: vault.hashicorp.com + failurePolicy: {{ ((.Values.injector.webhook)).failurePolicy | default .Values.injector.failurePolicy }} + matchPolicy: {{ ((.Values.injector.webhook)).matchPolicy | default "Exact" }} + sideEffects: None + timeoutSeconds: {{ ((.Values.injector.webhook)).timeoutSeconds | default "30" }} + admissionReviewVersions: ["v1", "v1beta1"] + clientConfig: + service: + name: {{ template "vault.fullname" . }}-agent-injector-svc + namespace: {{ include "vault.namespace" . }} + path: "/mutate" + caBundle: {{ .Values.injector.certs.caBundle | quote }} + rules: + - operations: ["CREATE"] + apiGroups: [""] + apiVersions: ["v1"] + resources: ["pods"] + scope: "Namespaced" +{{- if or (.Values.injector.namespaceSelector) (((.Values.injector.webhook)).namespaceSelector) }} + namespaceSelector: +{{ toYaml (((.Values.injector.webhook)).namespaceSelector | default .Values.injector.namespaceSelector) | indent 6}} +{{ end }} +{{- template "injector.objectSelector" . -}} +{{ end }} diff --git a/kubernetes-vault/vault/templates/injector-network-policy.yaml b/kubernetes-vault/vault/templates/injector-network-policy.yaml new file mode 100644 index 0000000..4c3b087 --- /dev/null +++ b/kubernetes-vault/vault/templates/injector-network-policy.yaml @@ -0,0 +1,29 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- template "vault.injectorEnabled" . -}} +{{- if .injectorEnabled -}} +{{- if eq (.Values.global.openshift | toString) "true" }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ template "vault.fullname" . }}-agent-injector + labels: + app.kubernetes.io/name: {{ template "vault.name" . }}-agent-injector + app.kubernetes.io/instance: {{ .Release.Name }} +spec: + podSelector: + matchLabels: + app.kubernetes.io/name: {{ template "vault.name" . }}-agent-injector + app.kubernetes.io/instance: {{ .Release.Name }} + component: webhook + ingress: + - from: + - namespaceSelector: {} + ports: + - port: 8080 + protocol: TCP +{{ end }} +{{ end }} diff --git a/kubernetes-vault/vault/templates/injector-psp-role.yaml b/kubernetes-vault/vault/templates/injector-psp-role.yaml new file mode 100644 index 0000000..a07f8f6 --- /dev/null +++ b/kubernetes-vault/vault/templates/injector-psp-role.yaml @@ -0,0 +1,25 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- template "vault.injectorEnabled" . -}} +{{- if .injectorEnabled -}} +{{- if eq (.Values.global.psp.enable | toString) "true" }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "vault.fullname" . }}-agent-injector-psp + namespace: {{ include "vault.namespace" . }} + labels: + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +rules: +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "vault.fullname" . }}-agent-injector +{{- end }} +{{- end }} diff --git a/kubernetes-vault/vault/templates/injector-psp-rolebinding.yaml b/kubernetes-vault/vault/templates/injector-psp-rolebinding.yaml new file mode 100644 index 0000000..3c97e8d --- /dev/null +++ b/kubernetes-vault/vault/templates/injector-psp-rolebinding.yaml @@ -0,0 +1,26 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- template "vault.injectorEnabled" . -}} +{{- if .injectorEnabled -}} +{{- if eq (.Values.global.psp.enable | toString) "true" }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "vault.fullname" . }}-agent-injector-psp + namespace: {{ include "vault.namespace" . }} + labels: + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +roleRef: + kind: Role + name: {{ template "vault.fullname" . }}-agent-injector-psp + apiGroup: rbac.authorization.k8s.io +subjects: + - kind: ServiceAccount + name: {{ template "vault.fullname" . }}-agent-injector +{{- end }} +{{- end }} \ No newline at end of file diff --git a/kubernetes-vault/vault/templates/injector-psp.yaml b/kubernetes-vault/vault/templates/injector-psp.yaml new file mode 100644 index 0000000..0eca9a8 --- /dev/null +++ b/kubernetes-vault/vault/templates/injector-psp.yaml @@ -0,0 +1,51 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- template "vault.injectorEnabled" . -}} +{{- if .injectorEnabled -}} +{{- if eq (.Values.global.psp.enable | toString) "true" }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "vault.fullname" . }}-agent-injector + labels: + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- template "vault.psp.annotations" . }} +spec: + privileged: false + # Required to prevent escalations to root. + allowPrivilegeEscalation: false + volumes: + - configMap + - emptyDir + - projected + - secret + - downwardAPI + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + # Require the container to run without root privileges. + rule: MustRunAsNonRoot + seLinux: + # This policy assumes the nodes are using AppArmor rather than SELinux. + rule: RunAsAny + supplementalGroups: + rule: MustRunAs + ranges: + # Forbid adding the root group. + - min: 1 + max: 65535 + fsGroup: + rule: MustRunAs + ranges: + # Forbid adding the root group. + - min: 1 + max: 65535 + readOnlyRootFilesystem: false +{{- end }} +{{- end }} \ No newline at end of file diff --git a/kubernetes-vault/vault/templates/injector-role.yaml b/kubernetes-vault/vault/templates/injector-role.yaml new file mode 100644 index 0000000..b2ad0c7 --- /dev/null +++ b/kubernetes-vault/vault/templates/injector-role.yaml @@ -0,0 +1,34 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- template "vault.injectorEnabled" . -}} +{{- if .injectorEnabled -}} +{{- if and (eq (.Values.injector.leaderElector.enabled | toString) "true") (gt (.Values.injector.replicas | int) 1) }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "vault.fullname" . }}-agent-injector-leader-elector-role + namespace: {{ include "vault.namespace" . }} + labels: + app.kubernetes.io/name: {{ include "vault.name" . }}-agent-injector + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +rules: + - apiGroups: [""] + resources: ["secrets", "configmaps"] + verbs: + - "create" + - "get" + - "watch" + - "list" + - "update" + - apiGroups: [""] + resources: ["pods"] + verbs: + - "get" + - "patch" + - "delete" +{{- end }} +{{- end }} \ No newline at end of file diff --git a/kubernetes-vault/vault/templates/injector-rolebinding.yaml b/kubernetes-vault/vault/templates/injector-rolebinding.yaml new file mode 100644 index 0000000..6ad25ca --- /dev/null +++ b/kubernetes-vault/vault/templates/injector-rolebinding.yaml @@ -0,0 +1,27 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- template "vault.injectorEnabled" . -}} +{{- if .injectorEnabled -}} +{{- if and (eq (.Values.injector.leaderElector.enabled | toString) "true") (gt (.Values.injector.replicas | int) 1) }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "vault.fullname" . }}-agent-injector-leader-elector-binding + namespace: {{ include "vault.namespace" . }} + labels: + app.kubernetes.io/name: {{ include "vault.name" . }}-agent-injector + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "vault.fullname" . }}-agent-injector-leader-elector-role +subjects: + - kind: ServiceAccount + name: {{ template "vault.fullname" . }}-agent-injector + namespace: {{ include "vault.namespace" . }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/kubernetes-vault/vault/templates/injector-service.yaml b/kubernetes-vault/vault/templates/injector-service.yaml new file mode 100644 index 0000000..1479cd1 --- /dev/null +++ b/kubernetes-vault/vault/templates/injector-service.yaml @@ -0,0 +1,27 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- template "vault.injectorEnabled" . -}} +{{- if .injectorEnabled -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "vault.fullname" . }}-agent-injector-svc + namespace: {{ include "vault.namespace" . }} + labels: + app.kubernetes.io/name: {{ include "vault.name" . }}-agent-injector + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + {{ template "injector.service.annotations" . }} +spec: + ports: + - name: https + port: 443 + targetPort: {{ .Values.injector.port }} + selector: + app.kubernetes.io/name: {{ include "vault.name" . }}-agent-injector + app.kubernetes.io/instance: {{ .Release.Name }} + component: webhook +{{- end }} diff --git a/kubernetes-vault/vault/templates/injector-serviceaccount.yaml b/kubernetes-vault/vault/templates/injector-serviceaccount.yaml new file mode 100644 index 0000000..2f91c3d --- /dev/null +++ b/kubernetes-vault/vault/templates/injector-serviceaccount.yaml @@ -0,0 +1,18 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- template "vault.injectorEnabled" . -}} +{{- if .injectorEnabled -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "vault.fullname" . }}-agent-injector + namespace: {{ include "vault.namespace" . }} + labels: + app.kubernetes.io/name: {{ include "vault.name" . }}-agent-injector + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + {{ template "injector.serviceAccount.annotations" . }} +{{ end }} diff --git a/kubernetes-vault/vault/templates/prometheus-prometheusrules.yaml b/kubernetes-vault/vault/templates/prometheus-prometheusrules.yaml new file mode 100644 index 0000000..7e58a0e --- /dev/null +++ b/kubernetes-vault/vault/templates/prometheus-prometheusrules.yaml @@ -0,0 +1,31 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{ if and (.Values.serverTelemetry.prometheusRules.rules) + (or (.Values.global.serverTelemetry.prometheusOperator) (.Values.serverTelemetry.prometheusRules.enabled) ) +}} +--- +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ template "vault.fullname" . }} + labels: + helm.sh/chart: {{ include "vault.chart" . }} + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + {{- /* update the selectors docs in values.yaml whenever the defaults below change. */ -}} + {{- $selectors := .Values.serverTelemetry.prometheusRules.selectors }} + {{- if $selectors }} + {{- toYaml $selectors | nindent 4 }} + {{- else }} + release: prometheus + {{- end }} +spec: + groups: + - name: {{ include "vault.fullname" . }} + rules: + {{- toYaml .Values.serverTelemetry.prometheusRules.rules | nindent 6 }} +{{- end }} diff --git a/kubernetes-vault/vault/templates/prometheus-servicemonitor.yaml b/kubernetes-vault/vault/templates/prometheus-servicemonitor.yaml new file mode 100644 index 0000000..62d924a --- /dev/null +++ b/kubernetes-vault/vault/templates/prometheus-servicemonitor.yaml @@ -0,0 +1,58 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{ template "vault.mode" . }} +{{ if or (.Values.global.serverTelemetry.prometheusOperator) (.Values.serverTelemetry.serviceMonitor.enabled) }} +--- +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "vault.fullname" . }} + labels: + helm.sh/chart: {{ include "vault.chart" . }} + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + {{- /* update the selectors docs in values.yaml whenever the defaults below change. */ -}} + {{- $selectors := .Values.serverTelemetry.serviceMonitor.selectors }} + {{- if $selectors }} + {{- toYaml $selectors | nindent 4 }} + {{- else }} + release: prometheus + {{- end }} +spec: + selector: + matchLabels: + app.kubernetes.io/name: {{ template "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + {{- if eq .mode "ha" }} + vault-active: "true" + {{- else }} + vault-internal: "true" + {{- end }} + endpoints: + - port: {{ include "vault.scheme" . }} + interval: {{ .Values.serverTelemetry.serviceMonitor.interval }} + scrapeTimeout: {{ .Values.serverTelemetry.serviceMonitor.scrapeTimeout }} + scheme: {{ include "vault.scheme" . | lower }} + path: /v1/sys/metrics + params: + format: + - prometheus + {{- with .Values.serverTelemetry.serviceMonitor.tlsConfig }} + tlsConfig: + {{- toYaml . | nindent 6 }} + {{- else }} + tlsConfig: + insecureSkipVerify: true + {{- end }} + {{- with .Values.serverTelemetry.serviceMonitor.authorization }} + authorization: + {{- toYaml . | nindent 6 }} + {{- end }} + namespaceSelector: + matchNames: + - {{ include "vault.namespace" . }} +{{ end }} diff --git a/kubernetes-vault/vault/templates/server-clusterrolebinding.yaml b/kubernetes-vault/vault/templates/server-clusterrolebinding.yaml new file mode 100644 index 0000000..14ec838 --- /dev/null +++ b/kubernetes-vault/vault/templates/server-clusterrolebinding.yaml @@ -0,0 +1,29 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{ template "vault.serverAuthDelegator" . }} +{{- if .serverAuthDelegator -}} +{{- if .Capabilities.APIVersions.Has "rbac.authorization.k8s.io/v1" -}} +apiVersion: rbac.authorization.k8s.io/v1 +{{- else }} +apiVersion: rbac.authorization.k8s.io/v1beta1 +{{- end }} +kind: ClusterRoleBinding +metadata: + name: {{ template "vault.fullname" . }}-server-binding + labels: + helm.sh/chart: {{ include "vault.chart" . }} + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:auth-delegator +subjects: +- kind: ServiceAccount + name: {{ template "vault.serviceAccount.name" . }} + namespace: {{ include "vault.namespace" . }} +{{ end }} \ No newline at end of file diff --git a/kubernetes-vault/vault/templates/server-config-configmap.yaml b/kubernetes-vault/vault/templates/server-config-configmap.yaml new file mode 100644 index 0000000..1fed2e6 --- /dev/null +++ b/kubernetes-vault/vault/templates/server-config-configmap.yaml @@ -0,0 +1,31 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{ template "vault.mode" . }} +{{- if ne .mode "external" }} +{{- if .serverEnabled -}} +{{- if ne .mode "dev" -}} +{{ if or (.Values.server.standalone.config) (.Values.server.ha.config) -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "vault.fullname" . }}-config + namespace: {{ include "vault.namespace" . }} + labels: + helm.sh/chart: {{ include "vault.chart" . }} + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- if .Values.server.includeConfigAnnotation }} + annotations: + vault.hashicorp.com/config-checksum: {{ include "vault.config" . | sha256sum }} +{{- end }} +data: + extraconfig-from-values.hcl: |- + {{ template "vault.config" . }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/vault/templates/server-discovery-role.yaml b/kubernetes-vault/vault/templates/server-discovery-role.yaml new file mode 100644 index 0000000..0cbdefa --- /dev/null +++ b/kubernetes-vault/vault/templates/server-discovery-role.yaml @@ -0,0 +1,26 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{ template "vault.mode" . }} +{{- if .serverEnabled -}} +{{- if eq .mode "ha" }} +{{- if eq (.Values.server.serviceAccount.serviceDiscovery.enabled | toString) "true" }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + namespace: {{ include "vault.namespace" . }} + name: {{ template "vault.fullname" . }}-discovery-role + labels: + helm.sh/chart: {{ include "vault.chart" . }} + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +rules: +- apiGroups: [""] + resources: ["pods"] + verbs: ["get", "watch", "list", "update", "patch"] +{{ end }} +{{ end }} +{{ end }} diff --git a/kubernetes-vault/vault/templates/server-discovery-rolebinding.yaml b/kubernetes-vault/vault/templates/server-discovery-rolebinding.yaml new file mode 100644 index 0000000..87b0f61 --- /dev/null +++ b/kubernetes-vault/vault/templates/server-discovery-rolebinding.yaml @@ -0,0 +1,34 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{ template "vault.mode" . }} +{{- if .serverEnabled -}} +{{- if eq .mode "ha" }} +{{- if eq (.Values.server.serviceAccount.serviceDiscovery.enabled | toString) "true" }} +{{- if .Capabilities.APIVersions.Has "rbac.authorization.k8s.io/v1" -}} +apiVersion: rbac.authorization.k8s.io/v1 +{{- else }} +apiVersion: rbac.authorization.k8s.io/v1beta1 +{{- end }} +kind: RoleBinding +metadata: + name: {{ template "vault.fullname" . }}-discovery-rolebinding + namespace: {{ include "vault.namespace" . }} + labels: + helm.sh/chart: {{ include "vault.chart" . }} + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "vault.fullname" . }}-discovery-role +subjects: +- kind: ServiceAccount + name: {{ template "vault.serviceAccount.name" . }} + namespace: {{ include "vault.namespace" . }} +{{ end }} +{{ end }} +{{ end }} diff --git a/kubernetes-vault/vault/templates/server-disruptionbudget.yaml b/kubernetes-vault/vault/templates/server-disruptionbudget.yaml new file mode 100644 index 0000000..bbe9eb2 --- /dev/null +++ b/kubernetes-vault/vault/templates/server-disruptionbudget.yaml @@ -0,0 +1,31 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{ template "vault.mode" . }} +{{- if ne .mode "external" -}} +{{- if .serverEnabled -}} +{{- if and (eq .mode "ha") (eq (.Values.server.ha.disruptionBudget.enabled | toString) "true") -}} +# PodDisruptionBudget to prevent degrading the server cluster through +# voluntary cluster changes. +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ template "vault.fullname" . }} + namespace: {{ include "vault.namespace" . }} + labels: + helm.sh/chart: {{ include "vault.chart" . }} + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +spec: + maxUnavailable: {{ template "vault.pdb.maxUnavailable" . }} + selector: + matchLabels: + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + component: server +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/kubernetes-vault/vault/templates/server-ha-active-service.yaml b/kubernetes-vault/vault/templates/server-ha-active-service.yaml new file mode 100644 index 0000000..9d2abfb --- /dev/null +++ b/kubernetes-vault/vault/templates/server-ha-active-service.yaml @@ -0,0 +1,64 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{ template "vault.mode" . }} +{{- if ne .mode "external" }} +{{- template "vault.serverServiceEnabled" . -}} +{{- if .serverServiceEnabled -}} +{{- if eq .mode "ha" }} +{{- if eq (.Values.server.service.active.enabled | toString) "true" }} +# Service for active Vault pod +apiVersion: v1 +kind: Service +metadata: + name: {{ template "vault.fullname" . }}-active + namespace: {{ include "vault.namespace" . }} + labels: + helm.sh/chart: {{ include "vault.chart" . }} + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + vault-active: "true" + annotations: +{{- template "vault.service.active.annotations" . }} +{{- template "vault.service.annotations" . }} +spec: + {{- if .Values.server.service.type}} + type: {{ .Values.server.service.type }} + {{- end}} + {{- if (semverCompare ">= 1.23-0" .Capabilities.KubeVersion.Version) }} + {{- if .Values.server.service.ipFamilyPolicy }} + ipFamilyPolicy: {{ .Values.server.service.ipFamilyPolicy }} + {{- end }} + {{- if .Values.server.service.ipFamilies }} + ipFamilies: {{ .Values.server.service.ipFamilies | toYaml | nindent 2 }} + {{- end }} + {{- end }} + {{- if .Values.server.service.clusterIP }} + clusterIP: {{ .Values.server.service.clusterIP }} + {{- end }} + {{- include "service.externalTrafficPolicy" .Values.server.service }} + publishNotReadyAddresses: {{ .Values.server.service.publishNotReadyAddresses }} + ports: + - name: {{ include "vault.scheme" . }} + port: {{ .Values.server.service.port }} + targetPort: {{ .Values.server.service.targetPort }} + {{- if and (.Values.server.service.activeNodePort) (eq (.Values.server.service.type | toString) "NodePort") }} + nodePort: {{ .Values.server.service.activeNodePort }} + {{- end }} + - name: https-internal + port: 8201 + targetPort: 8201 + selector: + app.kubernetes.io/name: {{ include "vault.name" . }} + {{- if eq (.Values.server.service.instanceSelector.enabled | toString) "true" }} + app.kubernetes.io/instance: {{ .Release.Name }} + {{- end }} + component: server + vault-active: "true" +{{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/vault/templates/server-ha-standby-service.yaml b/kubernetes-vault/vault/templates/server-ha-standby-service.yaml new file mode 100644 index 0000000..bae1e28 --- /dev/null +++ b/kubernetes-vault/vault/templates/server-ha-standby-service.yaml @@ -0,0 +1,63 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{ template "vault.mode" . }} +{{- if ne .mode "external" }} +{{- template "vault.serverServiceEnabled" . -}} +{{- if .serverServiceEnabled -}} +{{- if eq .mode "ha" }} +{{- if eq (.Values.server.service.standby.enabled | toString) "true" }} +# Service for standby Vault pod +apiVersion: v1 +kind: Service +metadata: + name: {{ template "vault.fullname" . }}-standby + namespace: {{ include "vault.namespace" . }} + labels: + helm.sh/chart: {{ include "vault.chart" . }} + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + annotations: +{{- template "vault.service.standby.annotations" . }} +{{- template "vault.service.annotations" . }} +spec: + {{- if .Values.server.service.type}} + type: {{ .Values.server.service.type }} + {{- end}} + {{- if (semverCompare ">= 1.23-0" .Capabilities.KubeVersion.Version) }} + {{- if .Values.server.service.ipFamilyPolicy }} + ipFamilyPolicy: {{ .Values.server.service.ipFamilyPolicy }} + {{- end }} + {{- if .Values.server.service.ipFamilies }} + ipFamilies: {{ .Values.server.service.ipFamilies | toYaml | nindent 2 }} + {{- end }} + {{- end }} + {{- if .Values.server.service.clusterIP }} + clusterIP: {{ .Values.server.service.clusterIP }} + {{- end }} + {{- include "service.externalTrafficPolicy" .Values.server.service }} + publishNotReadyAddresses: {{ .Values.server.service.publishNotReadyAddresses }} + ports: + - name: {{ include "vault.scheme" . }} + port: {{ .Values.server.service.port }} + targetPort: {{ .Values.server.service.targetPort }} + {{- if and (.Values.server.service.standbyNodePort) (eq (.Values.server.service.type | toString) "NodePort") }} + nodePort: {{ .Values.server.service.standbyNodePort }} + {{- end }} + - name: https-internal + port: 8201 + targetPort: 8201 + selector: + app.kubernetes.io/name: {{ include "vault.name" . }} + {{- if eq (.Values.server.service.instanceSelector.enabled | toString) "true" }} + app.kubernetes.io/instance: {{ .Release.Name }} + {{- end }} + component: server + vault-active: "false" +{{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/vault/templates/server-headless-service.yaml b/kubernetes-vault/vault/templates/server-headless-service.yaml new file mode 100644 index 0000000..c0f4d34 --- /dev/null +++ b/kubernetes-vault/vault/templates/server-headless-service.yaml @@ -0,0 +1,47 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{ template "vault.mode" . }} +{{- if ne .mode "external" }} +{{- template "vault.serverServiceEnabled" . -}} +{{- if .serverServiceEnabled -}} +# Service for Vault cluster +apiVersion: v1 +kind: Service +metadata: + name: {{ template "vault.fullname" . }}-internal + namespace: {{ include "vault.namespace" . }} + labels: + helm.sh/chart: {{ include "vault.chart" . }} + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + vault-internal: "true" + annotations: +{{ template "vault.service.annotations" .}} +spec: + {{- if (semverCompare ">= 1.23-0" .Capabilities.KubeVersion.Version) }} + {{- if .Values.server.service.ipFamilyPolicy }} + ipFamilyPolicy: {{ .Values.server.service.ipFamilyPolicy }} + {{- end }} + {{- if .Values.server.service.ipFamilies }} + ipFamilies: {{ .Values.server.service.ipFamilies | toYaml | nindent 2 }} + {{- end }} + {{- end }} + clusterIP: None + publishNotReadyAddresses: true + ports: + - name: "{{ include "vault.scheme" . }}" + port: {{ .Values.server.service.port }} + targetPort: {{ .Values.server.service.targetPort }} + - name: https-internal + port: 8201 + targetPort: 8201 + selector: + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + component: server +{{- end }} +{{- end }} diff --git a/kubernetes-vault/vault/templates/server-ingress.yaml b/kubernetes-vault/vault/templates/server-ingress.yaml new file mode 100644 index 0000000..d796bae --- /dev/null +++ b/kubernetes-vault/vault/templates/server-ingress.yaml @@ -0,0 +1,69 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- if not .Values.global.openshift }} +{{ template "vault.mode" . }} +{{- if ne .mode "external" }} +{{- if .Values.server.ingress.enabled -}} +{{- $extraPaths := .Values.server.ingress.extraPaths -}} +{{- $serviceName := include "vault.fullname" . -}} +{{- template "vault.serverServiceEnabled" . -}} +{{- if .serverServiceEnabled -}} +{{- if and (eq .mode "ha" ) (eq (.Values.server.ingress.activeService | toString) "true") }} +{{- $serviceName = printf "%s-%s" $serviceName "active" -}} +{{- end }} +{{- $servicePort := .Values.server.service.port -}} +{{- $pathType := .Values.server.ingress.pathType -}} +{{- $kubeVersion := .Capabilities.KubeVersion.Version }} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ template "vault.fullname" . }} + namespace: {{ include "vault.namespace" . }} + labels: + helm.sh/chart: {{ include "vault.chart" . }} + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + {{- with .Values.server.ingress.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- template "vault.ingress.annotations" . }} +spec: +{{- if .Values.server.ingress.tls }} + tls: + {{- range .Values.server.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} +{{- end }} +{{- if .Values.server.ingress.ingressClassName }} + ingressClassName: {{ .Values.server.ingress.ingressClassName }} +{{- end }} + rules: + {{- range .Values.server.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: +{{ if $extraPaths }} +{{ toYaml $extraPaths | indent 10 }} +{{- end }} + {{- range (.paths | default (list "/")) }} + - path: {{ . }} + pathType: {{ $pathType }} + backend: + service: + name: {{ $serviceName }} + port: + number: {{ $servicePort }} + {{- end }} + {{- end }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/vault/templates/server-network-policy.yaml b/kubernetes-vault/vault/templates/server-network-policy.yaml new file mode 100644 index 0000000..43dcdb1 --- /dev/null +++ b/kubernetes-vault/vault/templates/server-network-policy.yaml @@ -0,0 +1,24 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- if eq (.Values.server.networkPolicy.enabled | toString) "true" }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ template "vault.fullname" . }} + labels: + app.kubernetes.io/name: {{ template "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} +spec: + podSelector: + matchLabels: + app.kubernetes.io/name: {{ template "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + ingress: {{- toYaml .Values.server.networkPolicy.ingress | nindent 4 }} + {{- if .Values.server.networkPolicy.egress }} + egress: + {{- toYaml .Values.server.networkPolicy.egress | nindent 4 }} + {{ end }} +{{ end }} diff --git a/kubernetes-vault/vault/templates/server-psp-role.yaml b/kubernetes-vault/vault/templates/server-psp-role.yaml new file mode 100644 index 0000000..64cd6c5 --- /dev/null +++ b/kubernetes-vault/vault/templates/server-psp-role.yaml @@ -0,0 +1,25 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{ template "vault.mode" . }} +{{- if .serverEnabled -}} +{{- if and (ne .mode "") (eq (.Values.global.psp.enable | toString) "true") }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "vault.fullname" . }}-psp + namespace: {{ include "vault.namespace" . }} + labels: + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +rules: +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "vault.fullname" . }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/vault/templates/server-psp-rolebinding.yaml b/kubernetes-vault/vault/templates/server-psp-rolebinding.yaml new file mode 100644 index 0000000..342f553 --- /dev/null +++ b/kubernetes-vault/vault/templates/server-psp-rolebinding.yaml @@ -0,0 +1,26 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{ template "vault.mode" . }} +{{- if .serverEnabled -}} +{{- if and (ne .mode "") (eq (.Values.global.psp.enable | toString) "true") }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "vault.fullname" . }}-psp + namespace: {{ include "vault.namespace" . }} + labels: + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +roleRef: + kind: Role + name: {{ template "vault.fullname" . }}-psp + apiGroup: rbac.authorization.k8s.io +subjects: + - kind: ServiceAccount + name: {{ template "vault.fullname" . }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/vault/templates/server-psp.yaml b/kubernetes-vault/vault/templates/server-psp.yaml new file mode 100644 index 0000000..567e662 --- /dev/null +++ b/kubernetes-vault/vault/templates/server-psp.yaml @@ -0,0 +1,54 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{ template "vault.mode" . }} +{{- if .serverEnabled -}} +{{- if and (ne .mode "") (eq (.Values.global.psp.enable | toString) "true") }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "vault.fullname" . }} + labels: + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- template "vault.psp.annotations" . }} +spec: + privileged: false + # Required to prevent escalations to root. + allowPrivilegeEscalation: false + volumes: + - configMap + - emptyDir + - projected + - secret + - downwardAPI + {{- if eq (.Values.server.dataStorage.enabled | toString) "true" }} + - persistentVolumeClaim + {{- end }} + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + # Require the container to run without root privileges. + rule: MustRunAsNonRoot + seLinux: + # This policy assumes the nodes are using AppArmor rather than SELinux. + rule: RunAsAny + supplementalGroups: + rule: MustRunAs + ranges: + # Forbid adding the root group. + - min: 1 + max: 65535 + fsGroup: + rule: MustRunAs + ranges: + # Forbid adding the root group. + - min: 1 + max: 65535 + readOnlyRootFilesystem: false +{{- end }} +{{- end }} diff --git a/kubernetes-vault/vault/templates/server-route.yaml b/kubernetes-vault/vault/templates/server-route.yaml new file mode 100644 index 0000000..4e95555 --- /dev/null +++ b/kubernetes-vault/vault/templates/server-route.yaml @@ -0,0 +1,39 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- if .Values.global.openshift }} +{{- if ne .mode "external" }} +{{- if .Values.server.route.enabled -}} +{{- $serviceName := include "vault.fullname" . -}} +{{- if and (eq .mode "ha" ) (eq (.Values.server.route.activeService | toString) "true") }} +{{- $serviceName = printf "%s-%s" $serviceName "active" -}} +{{- end }} +kind: Route +apiVersion: route.openshift.io/v1 +metadata: + name: {{ template "vault.fullname" . }} + namespace: {{ include "vault.namespace" . }} + labels: + helm.sh/chart: {{ include "vault.chart" . }} + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + {{- with .Values.server.route.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- template "vault.route.annotations" . }} +spec: + host: {{ .Values.server.route.host }} + to: + kind: Service + name: {{ $serviceName }} + weight: 100 + port: + targetPort: 8200 + tls: + {{- toYaml .Values.server.route.tls | nindent 4 }} +{{- end }} +{{- end }} +{{- end }} diff --git a/kubernetes-vault/vault/templates/server-service.yaml b/kubernetes-vault/vault/templates/server-service.yaml new file mode 100644 index 0000000..c12e190 --- /dev/null +++ b/kubernetes-vault/vault/templates/server-service.yaml @@ -0,0 +1,59 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{ template "vault.mode" . }} +{{- if ne .mode "external" }} +{{- template "vault.serverServiceEnabled" . -}} +{{- if .serverServiceEnabled -}} +# Service for Vault cluster +apiVersion: v1 +kind: Service +metadata: + name: {{ template "vault.fullname" . }} + namespace: {{ include "vault.namespace" . }} + labels: + helm.sh/chart: {{ include "vault.chart" . }} + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + annotations: +{{ template "vault.service.annotations" .}} +spec: + {{- if .Values.server.service.type}} + type: {{ .Values.server.service.type }} + {{- end}} + {{- if (semverCompare ">= 1.23-0" .Capabilities.KubeVersion.Version) }} + {{- if .Values.server.service.ipFamilyPolicy }} + ipFamilyPolicy: {{ .Values.server.service.ipFamilyPolicy }} + {{- end }} + {{- if .Values.server.service.ipFamilies }} + ipFamilies: {{ .Values.server.service.ipFamilies | toYaml | nindent 2 }} + {{- end }} + {{- end }} + {{- if .Values.server.service.clusterIP }} + clusterIP: {{ .Values.server.service.clusterIP }} + {{- end }} + {{- include "service.externalTrafficPolicy" .Values.server.service }} + # We want the servers to become available even if they're not ready + # since this DNS is also used for join operations. + publishNotReadyAddresses: {{ .Values.server.service.publishNotReadyAddresses }} + ports: + - name: {{ include "vault.scheme" . }} + port: {{ .Values.server.service.port }} + targetPort: {{ .Values.server.service.targetPort }} + {{- if and (.Values.server.service.nodePort) (eq (.Values.server.service.type | toString) "NodePort") }} + nodePort: {{ .Values.server.service.nodePort }} + {{- end }} + - name: https-internal + port: 8201 + targetPort: 8201 + selector: + app.kubernetes.io/name: {{ include "vault.name" . }} + {{- if eq (.Values.server.service.instanceSelector.enabled | toString) "true" }} + app.kubernetes.io/instance: {{ .Release.Name }} + {{- end }} + component: server +{{- end }} +{{- end }} diff --git a/kubernetes-vault/vault/templates/server-serviceaccount-secret.yaml b/kubernetes-vault/vault/templates/server-serviceaccount-secret.yaml new file mode 100644 index 0000000..74d70f9 --- /dev/null +++ b/kubernetes-vault/vault/templates/server-serviceaccount-secret.yaml @@ -0,0 +1,21 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{ template "vault.serverServiceAccountSecretCreationEnabled" . }} +{{- if .serverServiceAccountSecretCreationEnabled -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "vault.serviceAccount.name" . }}-token + namespace: {{ include "vault.namespace" . }} + annotations: + kubernetes.io/service-account.name: {{ template "vault.serviceAccount.name" . }} + labels: + helm.sh/chart: {{ include "vault.chart" . }} + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +type: kubernetes.io/service-account-token +{{ end }} \ No newline at end of file diff --git a/kubernetes-vault/vault/templates/server-serviceaccount.yaml b/kubernetes-vault/vault/templates/server-serviceaccount.yaml new file mode 100644 index 0000000..216ea61 --- /dev/null +++ b/kubernetes-vault/vault/templates/server-serviceaccount.yaml @@ -0,0 +1,22 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{ template "vault.serverServiceAccountEnabled" . }} +{{- if .serverServiceAccountEnabled -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "vault.serviceAccount.name" . }} + namespace: {{ include "vault.namespace" . }} + labels: + helm.sh/chart: {{ include "vault.chart" . }} + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + {{- if .Values.server.serviceAccount.extraLabels -}} + {{- toYaml .Values.server.serviceAccount.extraLabels | nindent 4 -}} + {{- end -}} + {{ template "vault.serviceAccount.annotations" . }} +{{ end }} diff --git a/kubernetes-vault/vault/templates/server-statefulset.yaml b/kubernetes-vault/vault/templates/server-statefulset.yaml new file mode 100644 index 0000000..0d8e604 --- /dev/null +++ b/kubernetes-vault/vault/templates/server-statefulset.yaml @@ -0,0 +1,232 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{ template "vault.mode" . }} +{{- if ne .mode "external" }} +{{- if ne .mode "" }} +{{- if .serverEnabled -}} +# StatefulSet to run the actual vault server cluster. +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ template "vault.fullname" . }} + namespace: {{ include "vault.namespace" . }} + labels: + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + {{- template "vault.statefulSet.annotations" . }} +spec: + serviceName: {{ template "vault.fullname" . }}-internal + podManagementPolicy: Parallel + replicas: {{ template "vault.replicas" . }} + updateStrategy: + type: {{ .Values.server.updateStrategyType }} + {{- if and (semverCompare ">= 1.23-0" .Capabilities.KubeVersion.Version) (.Values.server.persistentVolumeClaimRetentionPolicy) }} + persistentVolumeClaimRetentionPolicy: {{ toYaml .Values.server.persistentVolumeClaimRetentionPolicy | nindent 4 }} + {{- end }} + selector: + matchLabels: + app.kubernetes.io/name: {{ template "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + component: server + template: + metadata: + labels: + helm.sh/chart: {{ template "vault.chart" . }} + app.kubernetes.io/name: {{ template "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + component: server + {{- if .Values.server.extraLabels -}} + {{- toYaml .Values.server.extraLabels | nindent 8 -}} + {{- end -}} + {{ template "vault.annotations" . }} + spec: + {{ template "vault.affinity" . }} + {{ template "vault.topologySpreadConstraints" . }} + {{ template "vault.tolerations" . }} + {{ template "vault.nodeselector" . }} + {{- if .Values.server.priorityClassName }} + priorityClassName: {{ .Values.server.priorityClassName }} + {{- end }} + terminationGracePeriodSeconds: {{ .Values.server.terminationGracePeriodSeconds }} + serviceAccountName: {{ template "vault.serviceAccount.name" . }} + {{ if .Values.server.shareProcessNamespace }} + shareProcessNamespace: true + {{ end }} + {{- template "server.statefulSet.securityContext.pod" . }} + {{- if not .Values.global.openshift }} + hostNetwork: {{ .Values.server.hostNetwork }} + {{- end }} + volumes: + {{ template "vault.volumes" . }} + - name: home + emptyDir: {} + {{- if .Values.server.hostAliases }} + hostAliases: + {{ toYaml .Values.server.hostAliases | nindent 8}} + {{- end }} + {{- if .Values.server.extraInitContainers }} + initContainers: + {{ toYaml .Values.server.extraInitContainers | nindent 8}} + {{- end }} + containers: + - name: vault + {{ template "vault.resources" . }} + image: {{ .Values.server.image.repository }}:{{ .Values.server.image.tag | default "latest" }} + imagePullPolicy: {{ .Values.server.image.pullPolicy }} + command: + - "/bin/sh" + - "-ec" + args: {{ template "vault.args" . }} + {{- template "server.statefulSet.securityContext.container" . }} + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: VAULT_K8S_POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: VAULT_K8S_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: VAULT_ADDR + value: "{{ include "vault.scheme" . }}://127.0.0.1:8200" + - name: VAULT_API_ADDR + {{- if .Values.server.ha.apiAddr }} + value: {{ .Values.server.ha.apiAddr }} + {{- else }} + value: "{{ include "vault.scheme" . }}://$(POD_IP):8200" + {{- end }} + - name: SKIP_CHOWN + value: "true" + - name: SKIP_SETCAP + value: "true" + - name: HOSTNAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: VAULT_CLUSTER_ADDR + {{- if .Values.server.ha.clusterAddr }} + value: {{ .Values.server.ha.clusterAddr | quote }} + {{- else }} + value: "https://$(HOSTNAME).{{ template "vault.fullname" . }}-internal:8201" + {{- end }} + {{- if and (eq (.Values.server.ha.raft.enabled | toString) "true") (eq (.Values.server.ha.raft.setNodeId | toString) "true") }} + - name: VAULT_RAFT_NODE_ID + valueFrom: + fieldRef: + fieldPath: metadata.name + {{- end }} + - name: HOME + value: "/home/vault" + {{- if .Values.server.logLevel }} + - name: VAULT_LOG_LEVEL + value: "{{ .Values.server.logLevel }}" + {{- end }} + {{- if .Values.server.logFormat }} + - name: VAULT_LOG_FORMAT + value: "{{ .Values.server.logFormat }}" + {{- end }} + {{- if (and .Values.server.enterpriseLicense.secretName .Values.server.enterpriseLicense.secretKey) }} + - name: VAULT_LICENSE_PATH + value: /vault/license/{{ .Values.server.enterpriseLicense.secretKey }} + {{- end }} + {{ template "vault.envs" . }} + {{- include "vault.extraEnvironmentVars" .Values.server | nindent 12 }} + {{- include "vault.extraSecretEnvironmentVars" .Values.server | nindent 12 }} + volumeMounts: + {{ template "vault.mounts" . }} + - name: home + mountPath: /home/vault + ports: + - containerPort: 8200 + name: {{ include "vault.scheme" . }} + - containerPort: 8201 + name: https-internal + - containerPort: 8202 + name: {{ include "vault.scheme" . }}-rep + {{- if .Values.server.extraPorts -}} + {{ toYaml .Values.server.extraPorts | nindent 12}} + {{- end }} + {{- if .Values.server.readinessProbe.enabled }} + readinessProbe: + {{- if .Values.server.readinessProbe.path }} + httpGet: + path: {{ .Values.server.readinessProbe.path | quote }} + port: {{ .Values.server.readinessProbe.port }} + scheme: {{ include "vault.scheme" . | upper }} + {{- else }} + # Check status; unsealed vault servers return 0 + # The exit code reflects the seal status: + # 0 - unsealed + # 1 - error + # 2 - sealed + exec: + command: ["/bin/sh", "-ec", "vault status -tls-skip-verify"] + {{- end }} + failureThreshold: {{ .Values.server.readinessProbe.failureThreshold }} + initialDelaySeconds: {{ .Values.server.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.server.readinessProbe.periodSeconds }} + successThreshold: {{ .Values.server.readinessProbe.successThreshold }} + timeoutSeconds: {{ .Values.server.readinessProbe.timeoutSeconds }} + {{- end }} + {{- if .Values.server.livenessProbe.enabled }} + livenessProbe: + {{- if .Values.server.livenessProbe.execCommand }} + exec: + command: + {{- range (.Values.server.livenessProbe.execCommand) }} + - {{ . | quote }} + {{- end }} + {{- else }} + httpGet: + path: {{ .Values.server.livenessProbe.path | quote }} + port: {{ .Values.server.livenessProbe.port }} + scheme: {{ include "vault.scheme" . | upper }} + {{- end }} + failureThreshold: {{ .Values.server.livenessProbe.failureThreshold }} + initialDelaySeconds: {{ .Values.server.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.server.livenessProbe.periodSeconds }} + successThreshold: {{ .Values.server.livenessProbe.successThreshold }} + timeoutSeconds: {{ .Values.server.livenessProbe.timeoutSeconds }} + {{- end }} + lifecycle: + # Vault container doesn't receive SIGTERM from Kubernetes + # and after the grace period ends, Kube sends SIGKILL. This + # causes issues with graceful shutdowns such as deregistering itself + # from Consul (zombie services). + preStop: + exec: + command: [ + "/bin/sh", "-c", + # Adding a sleep here to give the pod eviction a + # chance to propagate, so requests will not be made + # to this pod while it's terminating + "sleep {{ .Values.server.preStopSleepSeconds }} && kill -SIGTERM $(pidof vault)", + ] + {{- if .Values.server.postStart }} + postStart: + exec: + command: + {{- range (.Values.server.postStart) }} + - {{ . | quote }} + {{- end }} + {{- end }} + {{- if .Values.server.extraContainers }} + {{ toYaml .Values.server.extraContainers | nindent 8}} + {{- end }} + {{- include "imagePullSecrets" . | nindent 6 }} + {{ template "vault.volumeclaims" . }} +{{ end }} +{{ end }} +{{ end }} diff --git a/kubernetes-vault/vault/templates/tests/server-test.yaml b/kubernetes-vault/vault/templates/tests/server-test.yaml new file mode 100644 index 0000000..20e2e5a --- /dev/null +++ b/kubernetes-vault/vault/templates/tests/server-test.yaml @@ -0,0 +1,56 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{ template "vault.mode" . }} +{{- if ne .mode "external" }} +{{- if .serverEnabled -}} +apiVersion: v1 +kind: Pod +metadata: + name: {{ template "vault.fullname" . }}-server-test + namespace: {{ include "vault.namespace" . }} + annotations: + "helm.sh/hook": test +spec: + {{- include "imagePullSecrets" . | nindent 2 }} + containers: + - name: {{ .Release.Name }}-server-test + image: {{ .Values.server.image.repository }}:{{ .Values.server.image.tag | default "latest" }} + imagePullPolicy: {{ .Values.server.image.pullPolicy }} + env: + - name: VAULT_ADDR + value: {{ include "vault.scheme" . }}://{{ template "vault.fullname" . }}.{{ include "vault.namespace" . }}.svc:{{ .Values.server.service.port }} + {{- include "vault.extraEnvironmentVars" .Values.server | nindent 8 }} + command: + - /bin/sh + - -c + - | + echo "Checking for sealed info in 'vault status' output" + ATTEMPTS=10 + n=0 + until [ "$n" -ge $ATTEMPTS ] + do + echo "Attempt" $n... + vault status -format yaml | grep -E '^sealed: (true|false)' && break + n=$((n+1)) + sleep 5 + done + if [ $n -ge $ATTEMPTS ]; then + echo "timed out looking for sealed info in 'vault status' output" + exit 1 + fi + + exit 0 + volumeMounts: + {{- if .Values.server.volumeMounts }} + {{- toYaml .Values.server.volumeMounts | nindent 8}} + {{- end }} + volumes: + {{- if .Values.server.volumes }} + {{- toYaml .Values.server.volumes | nindent 4}} + {{- end }} + restartPolicy: Never +{{- end }} +{{- end }} diff --git a/kubernetes-vault/vault/templates/ui-service.yaml b/kubernetes-vault/vault/templates/ui-service.yaml new file mode 100644 index 0000000..9537084 --- /dev/null +++ b/kubernetes-vault/vault/templates/ui-service.yaml @@ -0,0 +1,50 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{ template "vault.mode" . }} +{{- if ne .mode "external" }} +{{- template "vault.uiEnabled" . -}} +{{- if .uiEnabled -}} + +apiVersion: v1 +kind: Service +metadata: + name: {{ template "vault.fullname" . }}-ui + namespace: {{ include "vault.namespace" . }} + labels: + helm.sh/chart: {{ include "vault.chart" . }} + app.kubernetes.io/name: {{ include "vault.name" . }}-ui + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + {{- template "vault.ui.annotations" . }} +spec: + {{- if (semverCompare ">= 1.23-0" .Capabilities.KubeVersion.Version) }} + {{- if .Values.ui.serviceIPFamilyPolicy }} + ipFamilyPolicy: {{ .Values.ui.serviceIPFamilyPolicy }} + {{- end }} + {{- if .Values.ui.serviceIPFamilies }} + ipFamilies: {{ .Values.ui.serviceIPFamilies | toYaml | nindent 2 }} + {{- end }} + {{- end }} + selector: + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + component: server + {{- if and (.Values.ui.activeVaultPodOnly) (eq .mode "ha") }} + vault-active: "true" + {{- end }} + publishNotReadyAddresses: {{ .Values.ui.publishNotReadyAddresses }} + ports: + - name: {{ include "vault.scheme" . }} + port: {{ .Values.ui.externalPort }} + targetPort: {{ .Values.ui.targetPort }} + {{- if .Values.ui.serviceNodePort }} + nodePort: {{ .Values.ui.serviceNodePort }} + {{- end }} + type: {{ .Values.ui.serviceType }} + {{- include "service.externalTrafficPolicy" .Values.ui }} + {{- include "service.loadBalancer" .Values.ui }} +{{- end -}} +{{- end }} diff --git a/kubernetes-vault/vault/values.openshift.yaml b/kubernetes-vault/vault/values.openshift.yaml new file mode 100644 index 0000000..369489f --- /dev/null +++ b/kubernetes-vault/vault/values.openshift.yaml @@ -0,0 +1,24 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +# These overrides are appropriate defaults for deploying this chart on OpenShift + +global: + openshift: true + +injector: + image: + repository: "registry.connect.redhat.com/hashicorp/vault-k8s" + tag: "1.4.2-ubi" + + agentImage: + repository: "registry.connect.redhat.com/hashicorp/vault" + tag: "1.17.2-ubi" + +server: + image: + repository: "registry.connect.redhat.com/hashicorp/vault" + tag: "1.17.2-ubi" + + readinessProbe: + path: "/v1/sys/health?uninitcode=204" diff --git a/kubernetes-vault/vault/values.schema.json b/kubernetes-vault/vault/values.schema.json new file mode 100644 index 0000000..7d62c13 --- /dev/null +++ b/kubernetes-vault/vault/values.schema.json @@ -0,0 +1,1309 @@ +{ + "$schema": "http://json-schema.org/schema#", + "type": "object", + "properties": { + "csi": { + "type": "object", + "properties": { + "agent": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "extraArgs": { + "type": "array" + }, + "image": { + "type": "object", + "properties": { + "pullPolicy": { + "type": "string" + }, + "repository": { + "type": "string" + }, + "tag": { + "type": "string" + } + } + }, + "logFormat": { + "type": "string" + }, + "logLevel": { + "type": "string" + }, + "resources": { + "type": "object" + } + } + }, + "daemonSet": { + "type": "object", + "properties": { + "annotations": { + "type": [ + "object", + "string" + ] + }, + "extraLabels": { + "type": "object" + }, + "kubeletRootDir": { + "type": "string" + }, + "providersDir": { + "type": "string" + }, + "securityContext": { + "type": "object", + "properties": { + "container": { + "type": [ + "object", + "string" + ] + }, + "pod": { + "type": [ + "object", + "string" + ] + } + } + }, + "updateStrategy": { + "type": "object", + "properties": { + "maxUnavailable": { + "type": "string" + }, + "type": { + "type": "string" + } + } + } + } + }, + "debug": { + "type": "boolean" + }, + "enabled": { + "type": [ + "boolean", + "string" + ] + }, + "extraArgs": { + "type": "array" + }, + "hmacSecretName": { + "type": "string" + }, + "image": { + "type": "object", + "properties": { + "pullPolicy": { + "type": "string" + }, + "repository": { + "type": "string" + }, + "tag": { + "type": "string" + } + } + }, + "livenessProbe": { + "type": "object", + "properties": { + "failureThreshold": { + "type": "integer" + }, + "initialDelaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "successThreshold": { + "type": "integer" + }, + "timeoutSeconds": { + "type": "integer" + } + } + }, + "pod": { + "type": "object", + "properties": { + "affinity": { + "type": [ + "null", + "object", + "string" + ] + }, + "annotations": { + "type": [ + "object", + "string" + ] + }, + "extraLabels": { + "type": "object" + }, + "nodeSelector": { + "type": [ + "null", + "object", + "string" + ] + }, + "tolerations": { + "type": [ + "null", + "array", + "string" + ] + } + } + }, + "priorityClassName": { + "type": "string" + }, + "readinessProbe": { + "type": "object", + "properties": { + "failureThreshold": { + "type": "integer" + }, + "initialDelaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "successThreshold": { + "type": "integer" + }, + "timeoutSeconds": { + "type": "integer" + } + } + }, + "resources": { + "type": "object" + }, + "serviceAccount": { + "type": "object", + "properties": { + "annotations": { + "type": [ + "object", + "string" + ] + }, + "extraLabels": { + "type": "object" + } + } + }, + "volumeMounts": { + "type": [ + "null", + "array" + ] + }, + "volumes": { + "type": [ + "null", + "array" + ] + } + } + }, + "global": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "externalVaultAddr": { + "type": "string" + }, + "imagePullSecrets": { + "type": "array" + }, + "namespace": { + "type": "string" + }, + "openshift": { + "type": "boolean" + }, + "psp": { + "type": "object", + "properties": { + "annotations": { + "type": [ + "object", + "string" + ] + }, + "enable": { + "type": "boolean" + } + } + }, + "serverTelemetry": { + "type": "object", + "properties": { + "prometheusOperator": { + "type": "boolean" + } + } + }, + "tlsDisable": { + "type": "boolean" + } + } + }, + "injector": { + "type": "object", + "properties": { + "affinity": { + "type": [ + "object", + "string" + ] + }, + "agentDefaults": { + "type": "object", + "properties": { + "cpuLimit": { + "type": "string" + }, + "cpuRequest": { + "type": "string" + }, + "memLimit": { + "type": "string" + }, + "memRequest": { + "type": "string" + }, + "ephemeralLimit": { + "type": "string" + }, + "ephemeralRequest": { + "type": "string" + }, + "template": { + "type": "string" + }, + "templateConfig": { + "type": "object", + "properties": { + "exitOnRetryFailure": { + "type": "boolean" + }, + "staticSecretRenderInterval": { + "type": "string" + } + } + } + } + }, + "agentImage": { + "type": "object", + "properties": { + "repository": { + "type": "string" + }, + "tag": { + "type": "string" + } + } + }, + "annotations": { + "type": [ + "object", + "string" + ] + }, + "authPath": { + "type": "string" + }, + "certs": { + "type": "object", + "properties": { + "caBundle": { + "type": "string" + }, + "certName": { + "type": "string" + }, + "keyName": { + "type": "string" + }, + "secretName": { + "type": [ + "null", + "string" + ] + } + } + }, + "enabled": { + "type": [ + "boolean", + "string" + ] + }, + "externalVaultAddr": { + "type": "string" + }, + "extraEnvironmentVars": { + "type": "object" + }, + "extraLabels": { + "type": "object" + }, + "failurePolicy": { + "type": "string" + }, + "hostNetwork": { + "type": "boolean" + }, + "image": { + "type": "object", + "properties": { + "pullPolicy": { + "type": "string" + }, + "repository": { + "type": "string" + }, + "tag": { + "type": "string" + } + } + }, + "leaderElector": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + } + } + }, + "livenessProbe": { + "type": "object", + "properties": { + "failureThreshold": { + "type": "integer" + }, + "initialDelaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "successThreshold": { + "type": "integer" + }, + "timeoutSeconds": { + "type": "integer" + } + } + }, + "logFormat": { + "type": "string" + }, + "logLevel": { + "type": "string" + }, + "metrics": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + } + } + }, + "namespaceSelector": { + "type": "object" + }, + "nodeSelector": { + "type": [ + "null", + "object", + "string" + ] + }, + "objectSelector": { + "type": [ + "object", + "string" + ] + }, + "podDisruptionBudget": { + "type": "object" + }, + "port": { + "type": "integer" + }, + "priorityClassName": { + "type": "string" + }, + "readinessProbe": { + "type": "object", + "properties": { + "failureThreshold": { + "type": "integer" + }, + "initialDelaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "successThreshold": { + "type": "integer" + }, + "timeoutSeconds": { + "type": "integer" + } + } + }, + "replicas": { + "type": "integer" + }, + "resources": { + "type": "object" + }, + "revokeOnShutdown": { + "type": "boolean" + }, + "securityContext": { + "type": "object", + "properties": { + "container": { + "type": [ + "object", + "string" + ] + }, + "pod": { + "type": [ + "object", + "string" + ] + } + } + }, + "service": { + "type": "object", + "properties": { + "annotations": { + "type": [ + "object", + "string" + ] + } + } + }, + "serviceAccount": { + "type": "object", + "properties": { + "annotations": { + "type": [ + "object", + "string" + ] + } + } + }, + "startupProbe": { + "type": "object", + "properties": { + "failureThreshold": { + "type": "integer" + }, + "initialDelaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "successThreshold": { + "type": "integer" + }, + "timeoutSeconds": { + "type": "integer" + } + } + }, + "strategy": { + "type": [ + "object", + "string" + ] + }, + "tolerations": { + "type": [ + "null", + "array", + "string" + ] + }, + "topologySpreadConstraints": { + "type": [ + "null", + "array", + "string" + ] + }, + "webhook": { + "type": "object", + "properties": { + "annotations": { + "type": [ + "object", + "string" + ] + }, + "failurePolicy": { + "type": "string" + }, + "matchPolicy": { + "type": "string" + }, + "namespaceSelector": { + "type": "object" + }, + "objectSelector": { + "type": [ + "object", + "string" + ] + }, + "timeoutSeconds": { + "type": "integer" + } + } + }, + "webhookAnnotations": { + "type": [ + "object", + "string" + ] + } + } + }, + "server": { + "type": "object", + "properties": { + "affinity": { + "type": [ + "object", + "string" + ] + }, + "annotations": { + "type": [ + "object", + "string" + ] + }, + "auditStorage": { + "type": "object", + "properties": { + "accessMode": { + "type": "string" + }, + "annotations": { + "type": [ + "object", + "string" + ] + }, + "enabled": { + "type": [ + "boolean", + "string" + ] + }, + "labels": { + "type": [ + "object", + "string" + ] + }, + "mountPath": { + "type": "string" + }, + "size": { + "type": "string" + }, + "storageClass": { + "type": [ + "null", + "string" + ] + } + } + }, + "authDelegator": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + } + } + }, + "configAnnotation": { + "type": "boolean" + }, + "dataStorage": { + "type": "object", + "properties": { + "accessMode": { + "type": "string" + }, + "annotations": { + "type": [ + "object", + "string" + ] + }, + "enabled": { + "type": [ + "boolean", + "string" + ] + }, + "labels": { + "type": [ + "object", + "string" + ] + }, + "mountPath": { + "type": "string" + }, + "size": { + "type": "string" + }, + "storageClass": { + "type": [ + "null", + "string" + ] + } + } + }, + "dev": { + "type": "object", + "properties": { + "devRootToken": { + "type": "string" + }, + "enabled": { + "type": "boolean" + } + } + }, + "enabled": { + "type": [ + "boolean", + "string" + ] + }, + "enterpriseLicense": { + "type": "object", + "properties": { + "secretKey": { + "type": "string" + }, + "secretName": { + "type": "string" + } + } + }, + "extraArgs": { + "type": "string" + }, + "extraContainers": { + "type": [ + "null", + "array" + ] + }, + "extraEnvironmentVars": { + "type": "object" + }, + "extraInitContainers": { + "type": [ + "null", + "array" + ] + }, + "extraLabels": { + "type": "object" + }, + "extraPorts": { + "type": [ + "null", + "array" + ] + }, + "extraSecretEnvironmentVars": { + "type": "array" + }, + "extraVolumes": { + "type": "array" + }, + "ha": { + "type": "object", + "properties": { + "apiAddr": { + "type": [ + "null", + "string" + ] + }, + "clusterAddr": { + "type": [ + "null", + "string" + ] + }, + "config": { + "type": [ + "string", + "object" + ] + }, + "disruptionBudget": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "maxUnavailable": { + "type": [ + "null", + "integer" + ] + } + } + }, + "enabled": { + "type": "boolean" + }, + "raft": { + "type": "object", + "properties": { + "config": { + "type": [ + "string", + "object" + ] + }, + "enabled": { + "type": "boolean" + }, + "setNodeId": { + "type": "boolean" + } + } + }, + "replicas": { + "type": "integer" + } + } + }, + "hostAliases": { + "type": "array" + }, + "hostNetwork": { + "type": "boolean" + }, + "image": { + "type": "object", + "properties": { + "pullPolicy": { + "type": "string" + }, + "repository": { + "type": "string" + }, + "tag": { + "type": "string" + } + } + }, + "ingress": { + "type": "object", + "properties": { + "activeService": { + "type": "boolean" + }, + "annotations": { + "type": [ + "object", + "string" + ] + }, + "enabled": { + "type": "boolean" + }, + "extraPaths": { + "type": "array" + }, + "hosts": { + "type": "array", + "items": { + "type": "object", + "properties": { + "host": { + "type": "string" + }, + "paths": { + "type": "array" + } + } + } + }, + "ingressClassName": { + "type": "string" + }, + "labels": { + "type": "object" + }, + "pathType": { + "type": "string" + }, + "tls": { + "type": "array" + } + } + }, + "livenessProbe": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "execCommand": { + "type": "array" + }, + "failureThreshold": { + "type": "integer" + }, + "initialDelaySeconds": { + "type": "integer" + }, + "path": { + "type": "string" + }, + "periodSeconds": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "successThreshold": { + "type": "integer" + }, + "timeoutSeconds": { + "type": "integer" + } + } + }, + "logFormat": { + "type": "string" + }, + "logLevel": { + "type": "string" + }, + "networkPolicy": { + "type": "object", + "properties": { + "egress": { + "type": "array" + }, + "enabled": { + "type": "boolean" + }, + "ingress": { + "type": "array" + } + } + }, + "nodeSelector": { + "type": [ + "null", + "object", + "string" + ] + }, + "persistentVolumeClaimRetentionPolicy": { + "type": "object", + "properties": { + "whenDeleted": { + "type": "string" + }, + "whenScaled": { + "type": "string" + } + } + }, + "postStart": { + "type": "array" + }, + "preStopSleepSeconds": { + "type": "integer" + }, + "priorityClassName": { + "type": "string" + }, + "readinessProbe": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "failureThreshold": { + "type": "integer" + }, + "initialDelaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "successThreshold": { + "type": "integer" + }, + "timeoutSeconds": { + "type": "integer" + } + } + }, + "resources": { + "type": "object" + }, + "route": { + "type": "object", + "properties": { + "activeService": { + "type": "boolean" + }, + "annotations": { + "type": [ + "object", + "string" + ] + }, + "enabled": { + "type": "boolean" + }, + "host": { + "type": "string" + }, + "labels": { + "type": "object" + }, + "tls": { + "type": "object" + } + } + }, + "service": { + "type": "object", + "properties": { + "active": { + "type": "object", + "properties": { + "annotations": { + "type": [ + "object", + "string" + ] + }, + "enabled": { + "type": "boolean" + } + } + }, + "activeNodePort": { + "type": "integer" + }, + "annotations": { + "type": [ + "object", + "string" + ] + }, + "enabled": { + "type": "boolean" + }, + "externalTrafficPolicy": { + "type": "string" + }, + "instanceSelector": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + } + } + }, + "ipFamilies": { + "type": "array" + }, + "ipFamilyPolicy": { + "type": "string" + }, + "nodePort": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "publishNotReadyAddresses": { + "type": "boolean" + }, + "standby": { + "type": "object", + "properties": { + "annotations": { + "type": [ + "object", + "string" + ] + }, + "enabled": { + "type": "boolean" + } + } + }, + "standbyNodePort": { + "type": "integer" + }, + "targetPort": { + "type": "integer" + } + } + }, + "serviceAccount": { + "type": "object", + "properties": { + "annotations": { + "type": [ + "object", + "string" + ] + }, + "create": { + "type": "boolean" + }, + "createSecret": { + "type": "boolean" + }, + "extraLabels": { + "type": "object" + }, + "name": { + "type": "string" + }, + "serviceDiscovery": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + } + } + } + } + }, + "shareProcessNamespace": { + "type": "boolean" + }, + "standalone": { + "type": "object", + "properties": { + "config": { + "type": [ + "string", + "object" + ] + }, + "enabled": { + "type": [ + "string", + "boolean" + ] + } + } + }, + "statefulSet": { + "type": "object", + "properties": { + "annotations": { + "type": [ + "object", + "string" + ] + }, + "securityContext": { + "type": "object", + "properties": { + "container": { + "type": [ + "object", + "string" + ] + }, + "pod": { + "type": [ + "object", + "string" + ] + } + } + } + } + }, + "terminationGracePeriodSeconds": { + "type": "integer" + }, + "tolerations": { + "type": [ + "null", + "array", + "string" + ] + }, + "topologySpreadConstraints": { + "type": [ + "null", + "array", + "string" + ] + }, + "updateStrategyType": { + "type": "string" + }, + "volumeMounts": { + "type": [ + "null", + "array" + ] + }, + "volumes": { + "type": [ + "null", + "array" + ] + } + } + }, + "serverTelemetry": { + "type": "object", + "properties": { + "prometheusRules": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "rules": { + "type": "array" + }, + "selectors": { + "type": "object" + } + } + }, + "serviceMonitor": { + "type": "object", + "properties": { + "authorization": { + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "interval": { + "type": "string" + }, + "scrapeTimeout": { + "type": "string" + }, + "selectors": { + "type": "object" + }, + "tlsConfig": { + "type": "object" + } + } + } + } + }, + "ui": { + "type": "object", + "properties": { + "activeVaultPodOnly": { + "type": "boolean" + }, + "annotations": { + "type": [ + "object", + "string" + ] + }, + "enabled": { + "type": [ + "boolean", + "string" + ] + }, + "externalPort": { + "type": "integer" + }, + "externalTrafficPolicy": { + "type": "string" + }, + "publishNotReadyAddresses": { + "type": "boolean" + }, + "serviceIPFamilies": { + "type": "array" + }, + "serviceIPFamilyPolicy": { + "type": "string" + }, + "serviceNodePort": { + "type": [ + "null", + "integer" + ] + }, + "serviceType": { + "type": "string" + }, + "targetPort": { + "type": "integer" + } + } + } + } +} diff --git a/kubernetes-vault/vault/values.yaml b/kubernetes-vault/vault/values.yaml new file mode 100644 index 0000000..8847798 --- /dev/null +++ b/kubernetes-vault/vault/values.yaml @@ -0,0 +1,1335 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +# Available parameters and their default values for the Vault chart. + +global: + # enabled is the master enabled switch. Setting this to true or false + # will enable or disable all the components within this chart by default. + enabled: true + + # The namespace to deploy to. Defaults to the `helm` installation namespace. + namespace: "" + + # Image pull secret to use for registry authentication. + # Alternatively, the value may be specified as an array of strings. + imagePullSecrets: [] + # imagePullSecrets: + # - name: image-pull-secret + + # TLS for end-to-end encrypted transport + tlsDisable: true + + # External vault server address for the injector and CSI provider to use. + # Setting this will disable deployment of a vault server. + externalVaultAddr: "" + + # If deploying to OpenShift + openshift: false + + # Create PodSecurityPolicy for pods + psp: + enable: false + # Annotation for PodSecurityPolicy. + # This is a multi-line templated string map, and can also be set as YAML. + annotations: | + seccomp.security.alpha.kubernetes.io/allowedProfileNames: docker/default,runtime/default + apparmor.security.beta.kubernetes.io/allowedProfileNames: runtime/default + seccomp.security.alpha.kubernetes.io/defaultProfileName: runtime/default + apparmor.security.beta.kubernetes.io/defaultProfileName: runtime/default + + serverTelemetry: + # Enable integration with the Prometheus Operator + # See the top level serverTelemetry section below before enabling this feature. + prometheusOperator: false + +injector: + # True if you want to enable vault agent injection. + # @default: global.enabled + enabled: "-" + + replicas: 1 + + # Configures the port the injector should listen on + port: 8080 + + # If multiple replicas are specified, by default a leader will be determined + # so that only one injector attempts to create TLS certificates. + leaderElector: + enabled: true + + # If true, will enable a node exporter metrics endpoint at /metrics. + metrics: + enabled: false + + # Deprecated: Please use global.externalVaultAddr instead. + externalVaultAddr: "" + + # image sets the repo and tag of the vault-k8s image to use for the injector. + image: + repository: "hashicorp/vault-k8s" + tag: "1.4.2" + pullPolicy: IfNotPresent + + # agentImage sets the repo and tag of the Vault image to use for the Vault Agent + # containers. This should be set to the official Vault image. Vault 1.3.1+ is + # required. + agentImage: + repository: "hashicorp/vault" + tag: "1.17.2" + + # The default values for the injected Vault Agent containers. + agentDefaults: + # For more information on configuring resources, see the K8s documentation: + # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + cpuLimit: "500m" + cpuRequest: "250m" + memLimit: "128Mi" + memRequest: "64Mi" + # ephemeralLimit: "128Mi" + # ephemeralRequest: "64Mi" + + # Default template type for secrets when no custom template is specified. + # Possible values include: "json" and "map". + template: "map" + + # Default values within Agent's template_config stanza. + templateConfig: + exitOnRetryFailure: true + staticSecretRenderInterval: "" + + # Used to define custom livenessProbe settings + livenessProbe: + # When a probe fails, Kubernetes will try failureThreshold times before giving up + failureThreshold: 2 + # Number of seconds after the container has started before probe initiates + initialDelaySeconds: 5 + # How often (in seconds) to perform the probe + periodSeconds: 2 + # Minimum consecutive successes for the probe to be considered successful after having failed + successThreshold: 1 + # Number of seconds after which the probe times out. + timeoutSeconds: 5 + # Used to define custom readinessProbe settings + readinessProbe: + # When a probe fails, Kubernetes will try failureThreshold times before giving up + failureThreshold: 2 + # Number of seconds after the container has started before probe initiates + initialDelaySeconds: 5 + # How often (in seconds) to perform the probe + periodSeconds: 2 + # Minimum consecutive successes for the probe to be considered successful after having failed + successThreshold: 1 + # Number of seconds after which the probe times out. + timeoutSeconds: 5 + # Used to define custom startupProbe settings + startupProbe: + # When a probe fails, Kubernetes will try failureThreshold times before giving up + failureThreshold: 12 + # Number of seconds after the container has started before probe initiates + initialDelaySeconds: 5 + # How often (in seconds) to perform the probe + periodSeconds: 5 + # Minimum consecutive successes for the probe to be considered successful after having failed + successThreshold: 1 + # Number of seconds after which the probe times out. + timeoutSeconds: 5 + + # Mount Path of the Vault Kubernetes Auth Method. + authPath: "auth/kubernetes" + + # Configures the log verbosity of the injector. + # Supported log levels include: trace, debug, info, warn, error + logLevel: "info" + + # Configures the log format of the injector. Supported log formats: "standard", "json". + logFormat: "standard" + + # Configures all Vault Agent sidecars to revoke their token when shutting down + revokeOnShutdown: false + + webhook: + # Configures failurePolicy of the webhook. The "unspecified" default behaviour depends on the + # API Version of the WebHook. + # To block pod creation while the webhook is unavailable, set the policy to `Fail` below. + # See https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#failure-policy + # + failurePolicy: Ignore + + # matchPolicy specifies the approach to accepting changes based on the rules of + # the MutatingWebhookConfiguration. + # See https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#matching-requests-matchpolicy + # for more details. + # + matchPolicy: Exact + + # timeoutSeconds is the amount of seconds before the webhook request will be ignored + # or fails. + # If it is ignored or fails depends on the failurePolicy + # See https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#timeouts + # for more details. + # + timeoutSeconds: 30 + + # namespaceSelector is the selector for restricting the webhook to only + # specific namespaces. + # See https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#matching-requests-namespaceselector + # for more details. + # Example: + # namespaceSelector: + # matchLabels: + # sidecar-injector: enabled + namespaceSelector: {} + + # objectSelector is the selector for restricting the webhook to only + # specific labels. + # See https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#matching-requests-objectselector + # for more details. + # Example: + # objectSelector: + # matchLabels: + # vault-sidecar-injector: enabled + objectSelector: | + matchExpressions: + - key: app.kubernetes.io/name + operator: NotIn + values: + - {{ template "vault.name" . }}-agent-injector + + # Extra annotations to attach to the webhook + annotations: {} + + # Deprecated: please use 'webhook.failurePolicy' instead + # Configures failurePolicy of the webhook. The "unspecified" default behaviour depends on the + # API Version of the WebHook. + # To block pod creation while webhook is unavailable, set the policy to `Fail` below. + # See https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#failure-policy + # + failurePolicy: Ignore + + # Deprecated: please use 'webhook.namespaceSelector' instead + # namespaceSelector is the selector for restricting the webhook to only + # specific namespaces. + # See https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#matching-requests-namespaceselector + # for more details. + # Example: + # namespaceSelector: + # matchLabels: + # sidecar-injector: enabled + namespaceSelector: {} + + # Deprecated: please use 'webhook.objectSelector' instead + # objectSelector is the selector for restricting the webhook to only + # specific labels. + # See https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#matching-requests-objectselector + # for more details. + # Example: + # objectSelector: + # matchLabels: + # vault-sidecar-injector: enabled + objectSelector: {} + + # Deprecated: please use 'webhook.annotations' instead + # Extra annotations to attach to the webhook + webhookAnnotations: {} + + certs: + # secretName is the name of the secret that has the TLS certificate and + # private key to serve the injector webhook. If this is null, then the + # injector will default to its automatic management mode that will assign + # a service account to the injector to generate its own certificates. + secretName: null + + # caBundle is a base64-encoded PEM-encoded certificate bundle for the CA + # that signed the TLS certificate that the webhook serves. This must be set + # if secretName is non-null unless an external service like cert-manager is + # keeping the caBundle updated. + caBundle: "" + + # certName and keyName are the names of the files within the secret for + # the TLS cert and private key, respectively. These have reasonable + # defaults but can be customized if necessary. + certName: tls.crt + keyName: tls.key + + # Security context for the pod template and the injector container + # The default pod securityContext is: + # runAsNonRoot: true + # runAsGroup: {{ .Values.injector.gid | default 1000 }} + # runAsUser: {{ .Values.injector.uid | default 100 }} + # fsGroup: {{ .Values.injector.gid | default 1000 }} + # and for container is + # allowPrivilegeEscalation: false + # capabilities: + # drop: + # - ALL + securityContext: + pod: {} + container: {} + + resources: {} + # resources: + # requests: + # memory: 256Mi + # cpu: 250m + # limits: + # memory: 256Mi + # cpu: 250m + + # extraEnvironmentVars is a list of extra environment variables to set in the + # injector deployment. + extraEnvironmentVars: {} + # KUBERNETES_SERVICE_HOST: kubernetes.default.svc + + # Affinity Settings for injector pods + # This can either be a multi-line string or YAML matching the PodSpec's affinity field. + # Commenting out or setting as empty the affinity variable, will allow + # deployment of multiple replicas to single node services such as Minikube. + affinity: | + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/name: {{ template "vault.name" . }}-agent-injector + app.kubernetes.io/instance: "{{ .Release.Name }}" + component: webhook + topologyKey: kubernetes.io/hostname + + # Topology settings for injector pods + # ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ + # This should be either a multi-line string or YAML matching the topologySpreadConstraints array + # in a PodSpec. + topologySpreadConstraints: [] + + # Toleration Settings for injector pods + # This should be either a multi-line string or YAML matching the Toleration array + # in a PodSpec. + tolerations: [] + + # nodeSelector labels for server pod assignment, formatted as a multi-line string or YAML map. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector + # Example: + # nodeSelector: + # beta.kubernetes.io/arch: amd64 + nodeSelector: {} + + # Priority class for injector pods + priorityClassName: "" + + # Extra annotations to attach to the injector pods + # This can either be YAML or a YAML-formatted multi-line templated string map + # of the annotations to apply to the injector pods + annotations: {} + + # Extra labels to attach to the agent-injector + # This should be a YAML map of the labels to apply to the injector + extraLabels: {} + + # Should the injector pods run on the host network (useful when using + # an alternate CNI in EKS) + hostNetwork: false + + # Injector service specific config + service: + # Extra annotations to attach to the injector service + annotations: {} + + # Injector serviceAccount specific config + serviceAccount: + # Extra annotations to attach to the injector serviceAccount + annotations: {} + + # A disruption budget limits the number of pods of a replicated application + # that are down simultaneously from voluntary disruptions + podDisruptionBudget: {} + # podDisruptionBudget: + # maxUnavailable: 1 + + # strategy for updating the deployment. This can be a multi-line string or a + # YAML map. + strategy: {} + # strategy: | + # rollingUpdate: + # maxSurge: 25% + # maxUnavailable: 25% + # type: RollingUpdate + +server: + # If true, or "-" with global.enabled true, Vault server will be installed. + # See vault.mode in _helpers.tpl for implementation details. + enabled: "-" + + # [Enterprise Only] This value refers to a Kubernetes secret that you have + # created that contains your enterprise license. If you are not using an + # enterprise image or if you plan to introduce the license key via another + # route, then leave secretName blank ("") or set it to null. + # Requires Vault Enterprise 1.8 or later. + enterpriseLicense: + # The name of the Kubernetes secret that holds the enterprise license. The + # secret must be in the same namespace that Vault is installed into. + secretName: "" + # The key within the Kubernetes secret that holds the enterprise license. + secretKey: "license" + + # Resource requests, limits, etc. for the server cluster placement. This + # should map directly to the value of the resources field for a PodSpec. + # By default no direct resource request is made. + + image: + repository: "hashicorp/vault" + tag: "1.17.2" + # Overrides the default Image Pull Policy + pullPolicy: IfNotPresent + + # Configure the Update Strategy Type for the StatefulSet + # See https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#update-strategies + updateStrategyType: "OnDelete" + + # Configure the logging verbosity for the Vault server. + # Supported log levels include: trace, debug, info, warn, error + logLevel: "" + + # Configure the logging format for the Vault server. + # Supported log formats include: standard, json + logFormat: "" + + resources: {} + # resources: + # requests: + # memory: 256Mi + # cpu: 250m + # limits: + # memory: 256Mi + # cpu: 250m + + # Ingress allows ingress services to be created to allow external access + # from Kubernetes to access Vault pods. + # If deployment is on OpenShift, the following block is ignored. + # In order to expose the service, use the route section below + ingress: + enabled: false + labels: {} + # traffic: external + annotations: {} + # | + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + # or + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + + # Optionally use ingressClassName instead of deprecated annotation. + # See: https://kubernetes.io/docs/concepts/services-networking/ingress/#deprecated-annotation + ingressClassName: "" + + # As of Kubernetes 1.19, all Ingress Paths must have a pathType configured. The default value below should be sufficient in most cases. + # See: https://kubernetes.io/docs/concepts/services-networking/ingress/#path-types for other possible values. + pathType: Prefix + + # When HA mode is enabled and K8s service registration is being used, + # configure the ingress to point to the Vault active service. + activeService: true + hosts: + - host: chart-example.local + paths: [] + ## Extra paths to prepend to the host configuration. This is useful when working with annotation based services. + extraPaths: [] + # - path: /* + # backend: + # service: + # name: ssl-redirect + # port: + # number: use-annotation + tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + + # hostAliases is a list of aliases to be added to /etc/hosts. Specified as a YAML list. + hostAliases: [] + # - ip: 127.0.0.1 + # hostnames: + # - chart-example.local + + # OpenShift only - create a route to expose the service + # By default the created route will be of type passthrough + route: + enabled: false + + # When HA mode is enabled and K8s service registration is being used, + # configure the route to point to the Vault active service. + activeService: true + + labels: {} + annotations: {} + host: chart-example.local + # tls will be passed directly to the route's TLS config, which + # can be used to configure other termination methods that terminate + # TLS at the router + tls: + termination: passthrough + + # authDelegator enables a cluster role binding to be attached to the service + # account. This cluster role binding can be used to setup Kubernetes auth + # method. See https://developer.hashicorp.com/vault/docs/auth/kubernetes + authDelegator: + enabled: true + + # extraInitContainers is a list of init containers. Specified as a YAML list. + # This is useful if you need to run a script to provision TLS certificates or + # write out configuration files in a dynamic way. + extraInitContainers: null + # # This example installs a plugin pulled from github into the /usr/local/libexec/vault/oauthapp folder, + # # which is defined in the volumes value. + # - name: oauthapp + # image: "alpine" + # command: [sh, -c] + # args: + # - cd /tmp && + # wget https://github.com/puppetlabs/vault-plugin-secrets-oauthapp/releases/download/v1.2.0/vault-plugin-secrets-oauthapp-v1.2.0-linux-amd64.tar.xz -O oauthapp.xz && + # tar -xf oauthapp.xz && + # mv vault-plugin-secrets-oauthapp-v1.2.0-linux-amd64 /usr/local/libexec/vault/oauthapp && + # chmod +x /usr/local/libexec/vault/oauthapp + # volumeMounts: + # - name: plugins + # mountPath: /usr/local/libexec/vault + + # extraContainers is a list of sidecar containers. Specified as a YAML list. + extraContainers: null + + # shareProcessNamespace enables process namespace sharing between Vault and the extraContainers + # This is useful if Vault must be signaled, e.g. to send a SIGHUP for a log rotation + shareProcessNamespace: false + + # extraArgs is a string containing additional Vault server arguments. + extraArgs: "" + + # extraPorts is a list of extra ports. Specified as a YAML list. + # This is useful if you need to add additional ports to the statefulset in dynamic way. + extraPorts: null + # - containerPort: 8300 + # name: http-monitoring + + # Used to define custom readinessProbe settings + readinessProbe: + enabled: true + # If you need to use a http path instead of the default exec + # path: /v1/sys/health?standbyok=true + + # Port number on which readinessProbe will be checked. + port: 8200 + # When a probe fails, Kubernetes will try failureThreshold times before giving up + failureThreshold: 2 + # Number of seconds after the container has started before probe initiates + initialDelaySeconds: 5 + # How often (in seconds) to perform the probe + periodSeconds: 5 + # Minimum consecutive successes for the probe to be considered successful after having failed + successThreshold: 1 + # Number of seconds after which the probe times out. + timeoutSeconds: 3 + # Used to enable a livenessProbe for the pods + livenessProbe: + enabled: false + # Used to define a liveness exec command. If provided, exec is preferred to httpGet (path) as the livenessProbe handler. + execCommand: [] + # - /bin/sh + # - -c + # - /vault/userconfig/mylivenessscript/run.sh + # Path for the livenessProbe to use httpGet as the livenessProbe handler + path: "/v1/sys/health?standbyok=true" + # Port number on which livenessProbe will be checked if httpGet is used as the livenessProbe handler + port: 8200 + # When a probe fails, Kubernetes will try failureThreshold times before giving up + failureThreshold: 2 + # Number of seconds after the container has started before probe initiates + initialDelaySeconds: 60 + # How often (in seconds) to perform the probe + periodSeconds: 5 + # Minimum consecutive successes for the probe to be considered successful after having failed + successThreshold: 1 + # Number of seconds after which the probe times out. + timeoutSeconds: 3 + + # Optional duration in seconds the pod needs to terminate gracefully. + # See: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/ + terminationGracePeriodSeconds: 10 + + # Used to set the sleep time during the preStop step + preStopSleepSeconds: 5 + + # Used to define commands to run after the pod is ready. + # This can be used to automate processes such as initialization + # or boostrapping auth methods. + postStart: [] + # - /bin/sh + # - -c + # - /vault/userconfig/myscript/run.sh + + # extraEnvironmentVars is a list of extra environment variables to set with the stateful set. These could be + # used to include variables required for auto-unseal. + extraEnvironmentVars: {} + # GOOGLE_REGION: global + # GOOGLE_PROJECT: myproject + # GOOGLE_APPLICATION_CREDENTIALS: /vault/userconfig/myproject/myproject-creds.json + + # extraSecretEnvironmentVars is a list of extra environment variables to set with the stateful set. + # These variables take value from existing Secret objects. + extraSecretEnvironmentVars: [] + # - envName: AWS_SECRET_ACCESS_KEY + # secretName: vault + # secretKey: AWS_SECRET_ACCESS_KEY + + # Deprecated: please use 'volumes' instead. + # extraVolumes is a list of extra volumes to mount. These will be exposed + # to Vault in the path `/vault/userconfig//`. The value below is + # an array of objects, examples are shown below. + extraVolumes: [] + # - type: secret (or "configMap") + # name: my-secret + # path: null # default is `/vault/userconfig` + + # volumes is a list of volumes made available to all containers. These are rendered + # via toYaml rather than pre-processed like the extraVolumes value. + # The purpose is to make it easy to share volumes between containers. + volumes: null + # - name: plugins + # emptyDir: {} + + # volumeMounts is a list of volumeMounts for the main server container. These are rendered + # via toYaml rather than pre-processed like the extraVolumes value. + # The purpose is to make it easy to share volumes between containers. + volumeMounts: null + # - mountPath: /usr/local/libexec/vault + # name: plugins + # readOnly: true + + # Affinity Settings + # Commenting out or setting as empty the affinity variable, will allow + # deployment to single node services such as Minikube + # This should be either a multi-line string or YAML matching the PodSpec's affinity field. + affinity: | + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/name: {{ template "vault.name" . }} + app.kubernetes.io/instance: "{{ .Release.Name }}" + component: server + topologyKey: kubernetes.io/hostname + + # Topology settings for server pods + # ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ + # This should be either a multi-line string or YAML matching the topologySpreadConstraints array + # in a PodSpec. + topologySpreadConstraints: [] + + # Toleration Settings for server pods + # This should be either a multi-line string or YAML matching the Toleration array + # in a PodSpec. + tolerations: [] + + # nodeSelector labels for server pod assignment, formatted as a multi-line string or YAML map. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector + # Example: + # nodeSelector: + # beta.kubernetes.io/arch: amd64 + nodeSelector: {} + + # Enables network policy for server pods + networkPolicy: + enabled: false + egress: [] + # egress: + # - to: + # - ipBlock: + # cidr: 10.0.0.0/24 + # ports: + # - protocol: TCP + # port: 443 + ingress: + - from: + - namespaceSelector: {} + ports: + - port: 8200 + protocol: TCP + - port: 8201 + protocol: TCP + + # Priority class for server pods + priorityClassName: "" + + # Extra labels to attach to the server pods + # This should be a YAML map of the labels to apply to the server pods + extraLabels: {} + + # Extra annotations to attach to the server pods + # This can either be YAML or a YAML-formatted multi-line templated string map + # of the annotations to apply to the server pods + annotations: {} + + # Add an annotation to the server configmap and the statefulset pods, + # vaultproject.io/config-checksum, that is a hash of the Vault configuration. + # This can be used together with an OnDelete deployment strategy to help + # identify which pods still need to be deleted during a deployment to pick up + # any configuration changes. + configAnnotation: false + + # Enables a headless service to be used by the Vault Statefulset + service: + enabled: true + # Enable or disable the vault-active service, which selects Vault pods that + # have labeled themselves as the cluster leader with `vault-active: "true"`. + active: + enabled: true + # Extra annotations for the service definition. This can either be YAML or a + # YAML-formatted multi-line templated string map of the annotations to apply + # to the active service. + annotations: {} + # Enable or disable the vault-standby service, which selects Vault pods that + # have labeled themselves as a cluster follower with `vault-active: "false"`. + standby: + enabled: true + # Extra annotations for the service definition. This can either be YAML or a + # YAML-formatted multi-line templated string map of the annotations to apply + # to the standby service. + annotations: {} + # If enabled, the service selectors will include `app.kubernetes.io/instance: {{ .Release.Name }}` + # When disabled, services may select Vault pods not deployed from the chart. + # Does not affect the headless vault-internal service with `ClusterIP: None` + instanceSelector: + enabled: true + # clusterIP controls whether a Cluster IP address is attached to the + # Vault service within Kubernetes. By default, the Vault service will + # be given a Cluster IP address, set to None to disable. When disabled + # Kubernetes will create a "headless" service. Headless services can be + # used to communicate with pods directly through DNS instead of a round-robin + # load balancer. + # clusterIP: None + + # Configures the service type for the main Vault service. Can be ClusterIP + # or NodePort. + #type: ClusterIP + + # The IP family and IP families options are to set the behaviour in a dual-stack environment. + # Omitting these values will let the service fall back to whatever the CNI dictates the defaults + # should be. + # These are only supported for kubernetes versions >=1.23.0 + # + # Configures the service's supported IP family policy, can be either: + # SingleStack: Single-stack service. The control plane allocates a cluster IP for the Service, using the first configured service cluster IP range. + # PreferDualStack: Allocates IPv4 and IPv6 cluster IPs for the Service. + # RequireDualStack: Allocates Service .spec.ClusterIPs from both IPv4 and IPv6 address ranges. + ipFamilyPolicy: "" + + # Sets the families that should be supported and the order in which they should be applied to ClusterIP as well. + # Can be IPv4 and/or IPv6. + ipFamilies: [] + + # Do not wait for pods to be ready before including them in the services' + # targets. Does not apply to the headless service, which is used for + # cluster-internal communication. + publishNotReadyAddresses: true + + # The externalTrafficPolicy can be set to either Cluster or Local + # and is only valid for LoadBalancer and NodePort service types. + # The default value is Cluster. + # ref: https://kubernetes.io/docs/concepts/services-networking/service/#external-traffic-policy + externalTrafficPolicy: Cluster + + # If type is set to "NodePort", a specific nodePort value can be configured, + # will be random if left blank. + #nodePort: 30000 + + # When HA mode is enabled + # If type is set to "NodePort", a specific nodePort value can be configured, + # will be random if left blank. + #activeNodePort: 30001 + + # When HA mode is enabled + # If type is set to "NodePort", a specific nodePort value can be configured, + # will be random if left blank. + #standbyNodePort: 30002 + + # Port on which Vault server is listening + port: 8200 + # Target port to which the service should be mapped to + targetPort: 8200 + # Extra annotations for the service definition. This can either be YAML or a + # YAML-formatted multi-line templated string map of the annotations to apply + # to the service. + annotations: {} + + # This configures the Vault Statefulset to create a PVC for data + # storage when using the file or raft backend storage engines. + # See https://developer.hashicorp.com/vault/docs/configuration/storage to know more + dataStorage: + enabled: true + # Size of the PVC created + size: 10Gi + # Location where the PVC will be mounted. + mountPath: "/vault/data" + # Name of the storage class to use. If null it will use the + # configured default Storage Class. + storageClass: null + # Access Mode of the storage device being used for the PVC + accessMode: ReadWriteOnce + # Annotations to apply to the PVC + annotations: {} + # Labels to apply to the PVC + labels: {} + + # Persistent Volume Claim (PVC) retention policy + # ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#persistentvolumeclaim-retention + # Example: + # persistentVolumeClaimRetentionPolicy: + # whenDeleted: Retain + # whenScaled: Retain + persistentVolumeClaimRetentionPolicy: {} + + # This configures the Vault Statefulset to create a PVC for audit + # logs. Once Vault is deployed, initialized, and unsealed, Vault must + # be configured to use this for audit logs. This will be mounted to + # /vault/audit + # See https://developer.hashicorp.com/vault/docs/audit to know more + auditStorage: + enabled: false + # Size of the PVC created + size: 10Gi + # Location where the PVC will be mounted. + mountPath: "/vault/audit" + # Name of the storage class to use. If null it will use the + # configured default Storage Class. + storageClass: null + # Access Mode of the storage device being used for the PVC + accessMode: ReadWriteOnce + # Annotations to apply to the PVC + annotations: {} + # Labels to apply to the PVC + labels: {} + + # Run Vault in "dev" mode. This requires no further setup, no state management, + # and no initialization. This is useful for experimenting with Vault without + # needing to unseal, store keys, et. al. All data is lost on restart - do not + # use dev mode for anything other than experimenting. + # See https://developer.hashicorp.com/vault/docs/concepts/dev-server to know more + dev: + enabled: false + + # Set VAULT_DEV_ROOT_TOKEN_ID value + devRootToken: "root" + + # Run Vault in "standalone" mode. This is the default mode that will deploy if + # no arguments are given to helm. This requires a PVC for data storage to use + # the "file" backend. This mode is not highly available and should not be scaled + # past a single replica. + standalone: + enabled: "-" + + # config is a raw string of default configuration when using a Stateful + # deployment. Default is to use a PersistentVolumeClaim mounted at /vault/data + # and store data there. This is only used when using a Replica count of 1, and + # using a stateful set. This should be HCL. + + # Note: Configuration files are stored in ConfigMaps so sensitive data + # such as passwords should be either mounted through extraSecretEnvironmentVars + # or through a Kube secret. For more information see: + # https://developer.hashicorp.com/vault/docs/platform/k8s/helm/run#protecting-sensitive-vault-configurations + config: | + ui = true + + listener "tcp" { + tls_disable = 1 + address = "[::]:8200" + cluster_address = "[::]:8201" + # Enable unauthenticated metrics access (necessary for Prometheus Operator) + #telemetry { + # unauthenticated_metrics_access = "true" + #} + } + storage "file" { + path = "/vault/data" + } + + # Example configuration for using auto-unseal, using Google Cloud KMS. The + # GKMS keys must already exist, and the cluster must have a service account + # that is authorized to access GCP KMS. + #seal "gcpckms" { + # project = "vault-helm-dev" + # region = "global" + # key_ring = "vault-helm-unseal-kr" + # crypto_key = "vault-helm-unseal-key" + #} + + # Example configuration for enabling Prometheus metrics in your config. + #telemetry { + # prometheus_retention_time = "30s" + # disable_hostname = true + #} + + # Run Vault in "HA" mode. There are no storage requirements unless the audit log + # persistence is required. In HA mode Vault will configure itself to use Consul + # for its storage backend. The default configuration provided will work the Consul + # Helm project by default. It is possible to manually configure Vault to use a + # different HA backend. + ha: + enabled: true + replicas: 3 + + # Set the api_addr configuration for Vault HA + # See https://developer.hashicorp.com/vault/docs/configuration#api_addr + # If set to null, this will be set to the Pod IP Address + apiAddr: null + + # Set the cluster_addr configuration for Vault HA + # See https://developer.hashicorp.com/vault/docs/configuration#cluster_addr + # If set to null, this will be set to https://$(HOSTNAME).{{ template "vault.fullname" . }}-internal:8201 + clusterAddr: null + + # Enables Vault's integrated Raft storage. Unlike the typical HA modes where + # Vault's persistence is external (such as Consul), enabling Raft mode will create + # persistent volumes for Vault to store data according to the configuration under server.dataStorage. + # The Vault cluster will coordinate leader elections and failovers internally. + raft: + + # Enables Raft integrated storage + enabled: false + # Set the Node Raft ID to the name of the pod + setNodeId: false + + # Note: Configuration files are stored in ConfigMaps so sensitive data + # such as passwords should be either mounted through extraSecretEnvironmentVars + # or through a Kube secret. For more information see: + # https://developer.hashicorp.com/vault/docs/platform/k8s/helm/run#protecting-sensitive-vault-configurations + config: | + ui = true + + listener "tcp" { + tls_disable = 1 + address = "[::]:8200" + cluster_address = "[::]:8201" + # Enable unauthenticated metrics access (necessary for Prometheus Operator) + #telemetry { + # unauthenticated_metrics_access = "true" + #} + } + + storage "raft" { + path = "/vault/data" + } + + service_registration "kubernetes" {} + + # config is a raw string of default configuration when using a Stateful + # deployment. Default is to use a Consul for its HA storage backend. + # This should be HCL. + + # Note: Configuration files are stored in ConfigMaps so sensitive data + # such as passwords should be either mounted through extraSecretEnvironmentVars + # or through a Kube secret. For more information see: + # https://developer.hashicorp.com/vault/docs/platform/k8s/helm/run#protecting-sensitive-vault-configurations + config: | + ui = true + + listener "tcp" { + tls_disable = 1 + address = "[::]:8200" + cluster_address = "[::]:8201" + } + storage "consul" { + path = "vault" + address = "consul-consul-server.consul.svc.cluster.local:8500" + } + + service_registration "kubernetes" {} + + # Example configuration for using auto-unseal, using Google Cloud KMS. The + # GKMS keys must already exist, and the cluster must have a service account + # that is authorized to access GCP KMS. + #seal "gcpckms" { + # project = "vault-helm-dev-246514" + # region = "global" + # key_ring = "vault-helm-unseal-kr" + # crypto_key = "vault-helm-unseal-key" + #} + + # Example configuration for enabling Prometheus metrics. + # If you are using Prometheus Operator you can enable a ServiceMonitor resource below. + # You may wish to enable unauthenticated metrics in the listener block above. + #telemetry { + # prometheus_retention_time = "30s" + # disable_hostname = true + #} + + # A disruption budget limits the number of pods of a replicated application + # that are down simultaneously from voluntary disruptions + disruptionBudget: + enabled: true + + # maxUnavailable will default to (n/2)-1 where n is the number of + # replicas. If you'd like a custom value, you can specify an override here. + maxUnavailable: null + + # Definition of the serviceAccount used to run Vault. + # These options are also used when using an external Vault server to validate + # Kubernetes tokens. + serviceAccount: + # Specifies whether a service account should be created + create: true + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + # Create a Secret API object to store a non-expiring token for the service account. + # Prior to v1.24.0, Kubernetes used to generate this secret for each service account by default. + # Kubernetes now recommends using short-lived tokens from the TokenRequest API or projected volumes instead if possible. + # For more details, see https://kubernetes.io/docs/concepts/configuration/secret/#service-account-token-secrets + # serviceAccount.create must be equal to 'true' in order to use this feature. + createSecret: false + # Extra annotations for the serviceAccount definition. This can either be + # YAML or a YAML-formatted multi-line templated string map of the + # annotations to apply to the serviceAccount. + annotations: {} + # Extra labels to attach to the serviceAccount + # This should be a YAML map of the labels to apply to the serviceAccount + extraLabels: {} + # Enable or disable a service account role binding with the permissions required for + # Vault's Kubernetes service_registration config option. + # See https://developer.hashicorp.com/vault/docs/configuration/service-registration/kubernetes + serviceDiscovery: + enabled: true + + # Settings for the statefulSet used to run Vault. + statefulSet: + # Extra annotations for the statefulSet. This can either be YAML or a + # YAML-formatted multi-line templated string map of the annotations to apply + # to the statefulSet. + annotations: {} + + # Set the pod and container security contexts. + # If not set, these will default to, and for *not* OpenShift: + # pod: + # runAsNonRoot: true + # runAsGroup: {{ .Values.server.gid | default 1000 }} + # runAsUser: {{ .Values.server.uid | default 100 }} + # fsGroup: {{ .Values.server.gid | default 1000 }} + # container: + # allowPrivilegeEscalation: false + # + # If not set, these will default to, and for OpenShift: + # pod: {} + # container: {} + securityContext: + pod: {} + container: {} + + # Should the server pods run on the host network + hostNetwork: false + +# Vault UI +ui: + # True if you want to create a Service entry for the Vault UI. + # + # serviceType can be used to control the type of service created. For + # example, setting this to "LoadBalancer" will create an external load + # balancer (for supported K8S installations) to access the UI. + enabled: false + publishNotReadyAddresses: true + # The service should only contain selectors for active Vault pod + activeVaultPodOnly: false + serviceType: "ClusterIP" + serviceNodePort: null + externalPort: 8200 + targetPort: 8200 + + # The IP family and IP families options are to set the behaviour in a dual-stack environment. + # Omitting these values will let the service fall back to whatever the CNI dictates the defaults + # should be. + # These are only supported for kubernetes versions >=1.23.0 + # + # Configures the service's supported IP family, can be either: + # SingleStack: Single-stack service. The control plane allocates a cluster IP for the Service, using the first configured service cluster IP range. + # PreferDualStack: Allocates IPv4 and IPv6 cluster IPs for the Service. + # RequireDualStack: Allocates Service .spec.ClusterIPs from both IPv4 and IPv6 address ranges. + serviceIPFamilyPolicy: "" + + # Sets the families that should be supported and the order in which they should be applied to ClusterIP as well + # Can be IPv4 and/or IPv6. + serviceIPFamilies: [] + + # The externalTrafficPolicy can be set to either Cluster or Local + # and is only valid for LoadBalancer and NodePort service types. + # The default value is Cluster. + # ref: https://kubernetes.io/docs/concepts/services-networking/service/#external-traffic-policy + externalTrafficPolicy: Cluster + + #loadBalancerSourceRanges: + # - 10.0.0.0/16 + # - 1.78.23.3/32 + + # loadBalancerIP: + + # Extra annotations to attach to the ui service + # This can either be YAML or a YAML-formatted multi-line templated string map + # of the annotations to apply to the ui service + annotations: {} + +# secrets-store-csi-driver-provider-vault +csi: + # True if you want to install a secrets-store-csi-driver-provider-vault daemonset. + # + # Requires installing the secrets-store-csi-driver separately, see: + # https://github.com/kubernetes-sigs/secrets-store-csi-driver#install-the-secrets-store-csi-driver + # + # With the driver and provider installed, you can mount Vault secrets into volumes + # similar to the Vault Agent injector, and you can also sync those secrets into + # Kubernetes secrets. + enabled: false + + image: + repository: "hashicorp/vault-csi-provider" + tag: "1.4.3" + pullPolicy: IfNotPresent + + # volumes is a list of volumes made available to all containers. These are rendered + # via toYaml rather than pre-processed like the extraVolumes value. + # The purpose is to make it easy to share volumes between containers. + volumes: null + # - name: tls + # secret: + # secretName: vault-tls + + # volumeMounts is a list of volumeMounts for the main server container. These are rendered + # via toYaml rather than pre-processed like the extraVolumes value. + # The purpose is to make it easy to share volumes between containers. + volumeMounts: null + # - name: tls + # mountPath: "/vault/tls" + # readOnly: true + + resources: {} + # resources: + # requests: + # cpu: 50m + # memory: 128Mi + # limits: + # cpu: 50m + # memory: 128Mi + + # Override the default secret name for the CSI Provider's HMAC key used for + # generating secret versions. + hmacSecretName: "" + + # Settings for the daemonSet used to run the provider. + daemonSet: + updateStrategy: + type: RollingUpdate + maxUnavailable: "" + # Extra annotations for the daemonSet. This can either be YAML or a + # YAML-formatted multi-line templated string map of the annotations to apply + # to the daemonSet. + annotations: {} + # Provider host path (must match the CSI provider's path) + providersDir: "/etc/kubernetes/secrets-store-csi-providers" + # Kubelet host path + kubeletRootDir: "/var/lib/kubelet" + # Extra labels to attach to the vault-csi-provider daemonSet + # This should be a YAML map of the labels to apply to the csi provider daemonSet + extraLabels: {} + # security context for the pod template and container in the csi provider daemonSet + securityContext: + pod: {} + container: {} + + pod: + # Extra annotations for the provider pods. This can either be YAML or a + # YAML-formatted multi-line templated string map of the annotations to apply + # to the pod. + annotations: {} + + # Toleration Settings for provider pods + # This should be either a multi-line string or YAML matching the Toleration array + # in a PodSpec. + tolerations: [] + + # nodeSelector labels for csi pod assignment, formatted as a multi-line string or YAML map. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector + # Example: + # nodeSelector: + # beta.kubernetes.io/arch: amd64 + nodeSelector: {} + + # Affinity Settings + # This should be either a multi-line string or YAML matching the PodSpec's affinity field. + affinity: {} + + # Extra labels to attach to the vault-csi-provider pod + # This should be a YAML map of the labels to apply to the csi provider pod + extraLabels: {} + + agent: + enabled: true + extraArgs: [] + + image: + repository: "hashicorp/vault" + tag: "1.17.2" + pullPolicy: IfNotPresent + + logFormat: standard + logLevel: info + + resources: {} + # resources: + # requests: + # memory: 256Mi + # cpu: 250m + # limits: + # memory: 256Mi + # cpu: 250m + + # Priority class for csi pods + priorityClassName: "" + + serviceAccount: + # Extra annotations for the serviceAccount definition. This can either be + # YAML or a YAML-formatted multi-line templated string map of the + # annotations to apply to the serviceAccount. + annotations: {} + + # Extra labels to attach to the vault-csi-provider serviceAccount + # This should be a YAML map of the labels to apply to the csi provider serviceAccount + extraLabels: {} + + # Used to configure readinessProbe for the pods. + readinessProbe: + # When a probe fails, Kubernetes will try failureThreshold times before giving up + failureThreshold: 2 + # Number of seconds after the container has started before probe initiates + initialDelaySeconds: 5 + # How often (in seconds) to perform the probe + periodSeconds: 5 + # Minimum consecutive successes for the probe to be considered successful after having failed + successThreshold: 1 + # Number of seconds after which the probe times out. + timeoutSeconds: 3 + # Used to configure livenessProbe for the pods. + livenessProbe: + # When a probe fails, Kubernetes will try failureThreshold times before giving up + failureThreshold: 2 + # Number of seconds after the container has started before probe initiates + initialDelaySeconds: 5 + # How often (in seconds) to perform the probe + periodSeconds: 5 + # Minimum consecutive successes for the probe to be considered successful after having failed + successThreshold: 1 + # Number of seconds after which the probe times out. + timeoutSeconds: 3 + + # Enables debug logging. + debug: false + + # Pass arbitrary additional arguments to vault-csi-provider. + # See https://developer.hashicorp.com/vault/docs/platform/k8s/csi/configurations#command-line-arguments + # for the available command line flags. + extraArgs: [] + +# Vault is able to collect and publish various runtime metrics. +# Enabling this feature requires setting adding `telemetry{}` stanza to +# the Vault configuration. There are a few examples included in the `config` sections above. +# +# For more information see: +# https://developer.hashicorp.com/vault/docs/configuration/telemetry +# https://developer.hashicorp.com/vault/docs/internals/telemetry +serverTelemetry: + # Enable support for the Prometheus Operator. If authorization is not set for authenticating + # to Vault's metrics endpoint, the following Vault server `telemetry{}` config must be included + # in the `listener "tcp"{}` stanza + # telemetry { + # unauthenticated_metrics_access = "true" + # } + # + # See the `standalone.config` for a more complete example of this. + # + # In addition, a top level `telemetry{}` stanza must also be included in the Vault configuration: + # + # example: + # telemetry { + # prometheus_retention_time = "30s" + # disable_hostname = true + # } + # + # Configuration for monitoring the Vault server. + serviceMonitor: + # The Prometheus operator *must* be installed before enabling this feature, + # if not the chart will fail to install due to missing CustomResourceDefinitions + # provided by the operator. + # + # Instructions on how to install the Helm chart can be found here: + # https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack + # More information can be found here: + # https://github.com/prometheus-operator/prometheus-operator + # https://github.com/prometheus-operator/kube-prometheus + + # Enable deployment of the Vault Server ServiceMonitor CustomResource. + enabled: false + + # Selector labels to add to the ServiceMonitor. + # When empty, defaults to: + # release: prometheus + selectors: {} + + # Interval at which Prometheus scrapes metrics + interval: 30s + + # Timeout for Prometheus scrapes + scrapeTimeout: 10s + + # tlsConfig used for scraping the Vault metrics API. + # See API reference: https://prometheus-operator.dev/docs/operator/api/#monitoring.coreos.com/v1.TLSConfig + # example: + # tlsConfig: + # ca: + # secret: + # name: vault-metrics-client + # key: ca.crt + tlsConfig: {} + + # authorization used for scraping the Vault metrics API. + # See API reference: https://prometheus-operator.dev/docs/operator/api/#monitoring.coreos.com/v1.SafeAuthorization + # example: + # authorization: + # credentials: + # name: vault-metrics-client + # key: token + authorization: {} + + prometheusRules: + # The Prometheus operator *must* be installed before enabling this feature, + # if not the chart will fail to install due to missing CustomResourceDefinitions + # provided by the operator. + + # Deploy the PrometheusRule custom resource for AlertManager based alerts. + # Requires that AlertManager is properly deployed. + enabled: false + + # Selector labels to add to the PrometheusRules. + # When empty, defaults to: + # release: prometheus + selectors: {} + + # Some example rules. + rules: [] + # - alert: vault-HighResponseTime + # annotations: + # message: The response time of Vault is over 500ms on average over the last 5 minutes. + # expr: vault_core_handle_request{quantile="0.5", namespace="mynamespace"} > 500 + # for: 5m + # labels: + # severity: warning + # - alert: vault-HighResponseTime + # annotations: + # message: The response time of Vault is over 1s on average over the last 5 minutes. + # expr: vault_core_handle_request{quantile="0.5", namespace="mynamespace"} > 1000 + # for: 5m + # labels: + # severity: critical