From 503dc78bfff983b21c383db3ca4dfbab8b38064f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 26 Sep 2024 00:57:05 +0000 Subject: [PATCH] Added chart versions: codefresh/cf-runtime: - 6.4.1 dell/csi-powerstore: - 2.11.1 dell/csi-unity: - 2.11.1 external-secrets/external-secrets: - 0.10.4 speedscale/speedscale-operator: - 2.2.467 --- assets/codefresh/cf-runtime-6.4.1.tgz | Bin 0 -> 43721 bytes assets/dell/csi-powerstore-2.11.1.tgz | Bin 0 -> 11504 bytes assets/dell/csi-unity-2.11.1.tgz | Bin 0 -> 9773 bytes .../external-secrets-0.10.4.tgz | Bin 0 -> 87289 bytes .../speedscale-operator-2.2.467.tgz | Bin 0 -> 17059 bytes charts/codefresh/cf-runtime/6.4.1/.helmignore | 3 + charts/codefresh/cf-runtime/6.4.1/Chart.yaml | 28 + charts/codefresh/cf-runtime/6.4.1/README.md | 1230 +++++ .../cf-runtime/6.4.1/README.md.gotmpl | 1007 ++++ .../cf-runtime/6.4.1/files/cleanup-runtime.sh | 37 + .../6.4.1/files/configure-dind-certs.sh | 132 + .../cf-runtime/6.4.1/files/init-runtime.sh | 80 + .../6.4.1/files/reconcile-runtime.sh | 38 + .../_components/app-proxy/_deployment.yaml | 70 + .../_components/app-proxy/_env-vars.yaml | 19 + .../_components/app-proxy/_helpers.tpl | 43 + .../_components/app-proxy/_ingress.yaml | 32 + .../_components/app-proxy/_rbac.yaml | 47 + .../_components/app-proxy/_service.yaml | 17 + .../event-exporter/_deployment.yaml | 62 + .../_components/event-exporter/_env-vars.yaml | 14 + .../_components/event-exporter/_helpers.tpl | 43 + .../_components/event-exporter/_rbac.yaml | 47 + .../_components/event-exporter/_service.yaml | 17 + .../event-exporter/_serviceMontor.yaml | 14 + .../_components/monitor/_deployment.yaml | 70 + .../_components/monitor/_env-vars.yaml | 26 + .../_components/monitor/_helpers.tpl | 42 + .../templates/_components/monitor/_rbac.yaml | 56 + .../_components/monitor/_service.yaml | 17 + .../_components/runner/_deployment.yaml | 103 + .../templates/_components/runner/_helpers.tpl | 42 + .../templates/_components/runner/_rbac.yaml | 53 + .../_init-container.yaml | 30 + .../_main-container.yaml | 28 + .../_sidecar-container.yaml | 22 + .../volume-provisioner/_cronjob.yaml | 58 + .../volume-provisioner/_daemonset.yaml | 98 + .../volume-provisioner/_deployment.yaml | 67 + .../volume-provisioner/_env-vars.yaml | 88 + .../volume-provisioner/_helpers.tpl | 93 + .../_components/volume-provisioner/_rbac.yaml | 71 + .../volume-provisioner/_secret.yaml | 22 + .../volume-provisioner/_storageclass.yaml | 47 + .../cf-runtime/6.4.1/templates/_helpers.tpl | 51 + .../6.4.1/templates/app-proxy/deployment.yaml | 9 + .../6.4.1/templates/app-proxy/ingress.yaml | 9 + .../6.4.1/templates/app-proxy/rbac.yaml | 9 + .../6.4.1/templates/app-proxy/service.yaml | 9 + .../templates/event-exporter/deployment.yaml | 9 + .../6.4.1/templates/event-exporter/rbac.yaml | 9 + .../templates/event-exporter/service.yaml | 11 + .../templates/extra/extra-resources.yaml | 6 + .../templates/extra/runtime-images-cm.yaml | 19 + .../hooks/post-install/cm-update-runtime.yaml | 18 + .../hooks/post-install/job-gencerts-dind.yaml | 68 + .../post-install/job-update-runtime.yaml | 77 + .../post-install/rbac-gencerts-dind.yaml | 37 + .../pre-delete/job-cleanup-resources.yaml | 73 + .../pre-delete/rbac-cleanup-resources.yaml | 46 + .../6.4.1/templates/monitor/deployment.yaml | 9 + .../6.4.1/templates/monitor/rbac.yaml | 9 + .../6.4.1/templates/monitor/service.yaml | 9 + .../templates/other/external-secrets.yaml | 2 + .../6.4.1/templates/other/podMonitor.yaml | 2 + .../6.4.1/templates/other/serviceMonitor.yaml | 2 + .../6.4.1/templates/runner/deployment.yaml | 9 + .../6.4.1/templates/runner/rbac.yaml | 9 + .../6.4.1/templates/runtime/_helpers.tpl | 123 + .../templates/runtime/cm-dind-daemon.yaml | 10 + .../6.4.1/templates/runtime/rbac.yaml | 48 + .../runtime/runtime-env-spec-tmpl.yaml | 214 + .../6.4.1/templates/runtime/secret.yaml | 11 + .../6.4.1/templates/runtime/svc-dind.yaml | 16 + .../templates/volume-provisioner/cronjob.yaml | 11 + .../volume-provisioner/daemonset.yaml | 11 + .../volume-provisioner/deployment.yaml | 10 + .../templates/volume-provisioner/rbac.yaml | 9 + .../templates/volume-provisioner/secret.yaml | 10 + .../volume-provisioner/storageclass.yaml | 10 + charts/codefresh/cf-runtime/6.4.1/values.yaml | 951 ++++ charts/dell/csi-powerstore/2.11.1/Chart.yaml | 23 + .../dell/csi-powerstore/2.11.1/app-readme.md | 92 + .../2.11.1/templates/_helpers.tpl | 10 + .../2.11.1/templates/controller.yaml | 457 ++ .../2.11.1/templates/csidriver.yaml | 27 + .../templates/driver-config-params.yaml | 31 + .../csi-powerstore/2.11.1/templates/node.yaml | 353 ++ charts/dell/csi-powerstore/2.11.1/values.yaml | 350 ++ charts/dell/csi-unity/2.11.1/Chart.yaml | 22 + charts/dell/csi-unity/2.11.1/app-readme.md | 93 + .../csi-unity/2.11.1/templates/_helpers.tpl | 10 + .../2.11.1/templates/controller.yaml | 328 ++ .../csi-unity/2.11.1/templates/csidriver.yaml | 12 + .../templates/driver-config-params.yaml | 18 + .../dell/csi-unity/2.11.1/templates/node.yaml | 283 + charts/dell/csi-unity/2.11.1/values.yaml | 273 + .../external-secrets/0.10.4/Chart.lock | 6 + .../external-secrets/0.10.4/Chart.yaml | 25 + .../external-secrets/0.10.4/README.md | 225 + .../external-secrets/0.10.4/app-readme.md | 7 + .../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/0.10.4/questions.yaml | 8 + .../0.10.4/templates/NOTES.txt | 7 + .../0.10.4/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 + .../0.10.4/templates/crds/acraccesstoken.yaml | 204 + .../templates/crds/clusterexternalsecret.yaml | 666 +++ .../templates/crds/clustersecretstore.yaml | 4640 +++++++++++++++++ .../templates/crds/ecrauthorizationtoken.yaml | 178 + .../0.10.4/templates/crds/externalsecret.yaml | 820 +++ .../0.10.4/templates/crds/fake.yaml | 87 + .../0.10.4/templates/crds/gcraccesstoken.yaml | 139 + .../templates/crds/githubaccesstoken.yaml | 113 + .../0.10.4/templates/crds/password.yaml | 109 + .../0.10.4/templates/crds/pushsecret.yaml | 388 ++ .../0.10.4/templates/crds/secretstore.yaml | 4640 +++++++++++++++++ .../0.10.4/templates/crds/uuid.yaml | 72 + .../templates/crds/vaultdynamicsecret.yaml | 708 +++ .../0.10.4/templates/crds/webhook.yaml | 158 + .../0.10.4/templates/deployment.yaml | 146 + .../0.10.4/templates/extra-manifests.yaml | 4 + .../0.10.4/templates/poddisruptionbudget.yaml | 19 + .../0.10.4/templates/rbac.yaml | 301 ++ .../0.10.4/templates/service.yaml | 28 + .../0.10.4/templates/serviceaccount.yaml | 16 + .../0.10.4/templates/servicemonitor.yaml | 164 + .../0.10.4/templates/validatingwebhook.yaml | 78 + .../0.10.4/templates/webhook-certificate.yaml | 30 + .../0.10.4/templates/webhook-deployment.yaml | 128 + .../webhook-poddisruptionbudget.yaml | 20 + .../0.10.4/templates/webhook-secret.yaml | 14 + .../0.10.4/templates/webhook-service.yaml | 37 + .../templates/webhook-serviceaccount.yaml | 16 + .../0.10.4/values.schema.json | 905 ++++ .../external-secrets/0.10.4/values.yaml | 532 ++ .../speedscale-operator/2.2.467/.helmignore | 23 + .../speedscale-operator/2.2.467/Chart.yaml | 27 + .../speedscale-operator/2.2.467/LICENSE | 201 + .../speedscale-operator/2.2.467/README.md | 111 + .../speedscale-operator/2.2.467/app-readme.md | 111 + .../2.2.467/questions.yaml | 9 + .../2.2.467/templates/NOTES.txt | 12 + .../2.2.467/templates/admission.yaml | 209 + .../2.2.467/templates/configmap.yaml | 43 + .../templates/crds/trafficreplays.yaml | 525 ++ .../2.2.467/templates/deployments.yaml | 132 + .../2.2.467/templates/hooks.yaml | 73 + .../2.2.467/templates/rbac.yaml | 244 + .../2.2.467/templates/secrets.yaml | 18 + .../2.2.467/templates/services.yaml | 22 + .../2.2.467/templates/tls.yaml | 183 + .../speedscale-operator/2.2.467/values.yaml | 138 + index.yaml | 147 +- 167 files changed, 27059 insertions(+), 1 deletion(-) create mode 100644 assets/codefresh/cf-runtime-6.4.1.tgz create mode 100644 assets/dell/csi-powerstore-2.11.1.tgz create mode 100644 assets/dell/csi-unity-2.11.1.tgz create mode 100644 assets/external-secrets/external-secrets-0.10.4.tgz create mode 100644 assets/speedscale/speedscale-operator-2.2.467.tgz create mode 100644 charts/codefresh/cf-runtime/6.4.1/.helmignore create mode 100644 charts/codefresh/cf-runtime/6.4.1/Chart.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/README.md create mode 100644 charts/codefresh/cf-runtime/6.4.1/README.md.gotmpl create mode 100644 charts/codefresh/cf-runtime/6.4.1/files/cleanup-runtime.sh create mode 100644 charts/codefresh/cf-runtime/6.4.1/files/configure-dind-certs.sh create mode 100644 charts/codefresh/cf-runtime/6.4.1/files/init-runtime.sh create mode 100644 charts/codefresh/cf-runtime/6.4.1/files/reconcile-runtime.sh create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/_components/app-proxy/_deployment.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/_components/app-proxy/_env-vars.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/_components/app-proxy/_helpers.tpl create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/_components/app-proxy/_ingress.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/_components/app-proxy/_rbac.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/_components/app-proxy/_service.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/_components/event-exporter/_deployment.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/_components/event-exporter/_env-vars.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/_components/event-exporter/_helpers.tpl create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/_components/event-exporter/_rbac.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/_components/event-exporter/_service.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/_components/event-exporter/_serviceMontor.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/_components/monitor/_deployment.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/_components/monitor/_env-vars.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/_components/monitor/_helpers.tpl create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/_components/monitor/_rbac.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/_components/monitor/_service.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/_components/runner/_deployment.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/_components/runner/_helpers.tpl create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/_components/runner/_rbac.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/_components/runner/environment-variables/_init-container.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/_components/runner/environment-variables/_main-container.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/_components/runner/environment-variables/_sidecar-container.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/_components/volume-provisioner/_cronjob.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/_components/volume-provisioner/_daemonset.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/_components/volume-provisioner/_deployment.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/_components/volume-provisioner/_env-vars.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/_components/volume-provisioner/_helpers.tpl create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/_components/volume-provisioner/_rbac.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/_components/volume-provisioner/_secret.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/_components/volume-provisioner/_storageclass.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/_helpers.tpl create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/app-proxy/deployment.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/app-proxy/ingress.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/app-proxy/rbac.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/app-proxy/service.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/event-exporter/deployment.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/event-exporter/rbac.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/event-exporter/service.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/extra/extra-resources.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/extra/runtime-images-cm.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/hooks/post-install/cm-update-runtime.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/hooks/post-install/job-gencerts-dind.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/hooks/post-install/job-update-runtime.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/hooks/post-install/rbac-gencerts-dind.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/hooks/pre-delete/job-cleanup-resources.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/hooks/pre-delete/rbac-cleanup-resources.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/monitor/deployment.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/monitor/rbac.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/monitor/service.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/other/external-secrets.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/other/podMonitor.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/other/serviceMonitor.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/runner/deployment.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/runner/rbac.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/runtime/_helpers.tpl create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/runtime/cm-dind-daemon.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/runtime/rbac.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/runtime/runtime-env-spec-tmpl.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/runtime/secret.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/runtime/svc-dind.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/volume-provisioner/cronjob.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/volume-provisioner/daemonset.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/volume-provisioner/deployment.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/volume-provisioner/rbac.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/volume-provisioner/secret.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/templates/volume-provisioner/storageclass.yaml create mode 100644 charts/codefresh/cf-runtime/6.4.1/values.yaml create mode 100644 charts/dell/csi-powerstore/2.11.1/Chart.yaml create mode 100644 charts/dell/csi-powerstore/2.11.1/app-readme.md create mode 100644 charts/dell/csi-powerstore/2.11.1/templates/_helpers.tpl create mode 100644 charts/dell/csi-powerstore/2.11.1/templates/controller.yaml create mode 100644 charts/dell/csi-powerstore/2.11.1/templates/csidriver.yaml create mode 100644 charts/dell/csi-powerstore/2.11.1/templates/driver-config-params.yaml create mode 100644 charts/dell/csi-powerstore/2.11.1/templates/node.yaml create mode 100644 charts/dell/csi-powerstore/2.11.1/values.yaml create mode 100644 charts/dell/csi-unity/2.11.1/Chart.yaml create mode 100644 charts/dell/csi-unity/2.11.1/app-readme.md create mode 100644 charts/dell/csi-unity/2.11.1/templates/_helpers.tpl create mode 100644 charts/dell/csi-unity/2.11.1/templates/controller.yaml create mode 100644 charts/dell/csi-unity/2.11.1/templates/csidriver.yaml create mode 100644 charts/dell/csi-unity/2.11.1/templates/driver-config-params.yaml create mode 100644 charts/dell/csi-unity/2.11.1/templates/node.yaml create mode 100644 charts/dell/csi-unity/2.11.1/values.yaml create mode 100644 charts/external-secrets/external-secrets/0.10.4/Chart.lock create mode 100644 charts/external-secrets/external-secrets/0.10.4/Chart.yaml create mode 100644 charts/external-secrets/external-secrets/0.10.4/README.md create mode 100644 charts/external-secrets/external-secrets/0.10.4/app-readme.md create mode 100644 charts/external-secrets/external-secrets/0.10.4/charts/bitwarden-sdk-server/.helmignore create mode 100644 charts/external-secrets/external-secrets/0.10.4/charts/bitwarden-sdk-server/Chart.yaml create mode 100644 charts/external-secrets/external-secrets/0.10.4/charts/bitwarden-sdk-server/templates/NOTES.txt create mode 100644 charts/external-secrets/external-secrets/0.10.4/charts/bitwarden-sdk-server/templates/_helpers.tpl create mode 100644 charts/external-secrets/external-secrets/0.10.4/charts/bitwarden-sdk-server/templates/deployment.yaml create mode 100644 charts/external-secrets/external-secrets/0.10.4/charts/bitwarden-sdk-server/templates/service.yaml create mode 100644 charts/external-secrets/external-secrets/0.10.4/charts/bitwarden-sdk-server/templates/serviceaccount.yaml create mode 100644 charts/external-secrets/external-secrets/0.10.4/charts/bitwarden-sdk-server/tests/__snapshot__/deployment_test.yaml.snap create mode 100644 charts/external-secrets/external-secrets/0.10.4/charts/bitwarden-sdk-server/tests/deployment_test.yaml create mode 100644 charts/external-secrets/external-secrets/0.10.4/charts/bitwarden-sdk-server/values.yaml create mode 100644 charts/external-secrets/external-secrets/0.10.4/questions.yaml create mode 100644 charts/external-secrets/external-secrets/0.10.4/templates/NOTES.txt create mode 100644 charts/external-secrets/external-secrets/0.10.4/templates/_helpers.tpl create mode 100644 charts/external-secrets/external-secrets/0.10.4/templates/cert-controller-deployment.yaml create mode 100644 charts/external-secrets/external-secrets/0.10.4/templates/cert-controller-poddisruptionbudget.yaml create mode 100644 charts/external-secrets/external-secrets/0.10.4/templates/cert-controller-rbac.yaml create mode 100644 charts/external-secrets/external-secrets/0.10.4/templates/cert-controller-service.yaml create mode 100644 charts/external-secrets/external-secrets/0.10.4/templates/cert-controller-serviceaccount.yaml create mode 100644 charts/external-secrets/external-secrets/0.10.4/templates/crds/acraccesstoken.yaml create mode 100644 charts/external-secrets/external-secrets/0.10.4/templates/crds/clusterexternalsecret.yaml create mode 100644 charts/external-secrets/external-secrets/0.10.4/templates/crds/clustersecretstore.yaml create mode 100644 charts/external-secrets/external-secrets/0.10.4/templates/crds/ecrauthorizationtoken.yaml create mode 100644 charts/external-secrets/external-secrets/0.10.4/templates/crds/externalsecret.yaml create mode 100644 charts/external-secrets/external-secrets/0.10.4/templates/crds/fake.yaml create mode 100644 charts/external-secrets/external-secrets/0.10.4/templates/crds/gcraccesstoken.yaml create mode 100644 charts/external-secrets/external-secrets/0.10.4/templates/crds/githubaccesstoken.yaml create mode 100644 charts/external-secrets/external-secrets/0.10.4/templates/crds/password.yaml create mode 100644 charts/external-secrets/external-secrets/0.10.4/templates/crds/pushsecret.yaml create mode 100644 charts/external-secrets/external-secrets/0.10.4/templates/crds/secretstore.yaml create mode 100644 charts/external-secrets/external-secrets/0.10.4/templates/crds/uuid.yaml create mode 100644 charts/external-secrets/external-secrets/0.10.4/templates/crds/vaultdynamicsecret.yaml create mode 100644 charts/external-secrets/external-secrets/0.10.4/templates/crds/webhook.yaml create mode 100644 charts/external-secrets/external-secrets/0.10.4/templates/deployment.yaml create mode 100644 charts/external-secrets/external-secrets/0.10.4/templates/extra-manifests.yaml create mode 100644 charts/external-secrets/external-secrets/0.10.4/templates/poddisruptionbudget.yaml create mode 100644 charts/external-secrets/external-secrets/0.10.4/templates/rbac.yaml create mode 100644 charts/external-secrets/external-secrets/0.10.4/templates/service.yaml create mode 100644 charts/external-secrets/external-secrets/0.10.4/templates/serviceaccount.yaml create mode 100644 charts/external-secrets/external-secrets/0.10.4/templates/servicemonitor.yaml create mode 100644 charts/external-secrets/external-secrets/0.10.4/templates/validatingwebhook.yaml create mode 100644 charts/external-secrets/external-secrets/0.10.4/templates/webhook-certificate.yaml create mode 100644 charts/external-secrets/external-secrets/0.10.4/templates/webhook-deployment.yaml create mode 100644 charts/external-secrets/external-secrets/0.10.4/templates/webhook-poddisruptionbudget.yaml create mode 100644 charts/external-secrets/external-secrets/0.10.4/templates/webhook-secret.yaml create mode 100644 charts/external-secrets/external-secrets/0.10.4/templates/webhook-service.yaml create mode 100644 charts/external-secrets/external-secrets/0.10.4/templates/webhook-serviceaccount.yaml create mode 100644 charts/external-secrets/external-secrets/0.10.4/values.schema.json create mode 100644 charts/external-secrets/external-secrets/0.10.4/values.yaml create mode 100644 charts/speedscale/speedscale-operator/2.2.467/.helmignore create mode 100644 charts/speedscale/speedscale-operator/2.2.467/Chart.yaml create mode 100644 charts/speedscale/speedscale-operator/2.2.467/LICENSE create mode 100644 charts/speedscale/speedscale-operator/2.2.467/README.md create mode 100644 charts/speedscale/speedscale-operator/2.2.467/app-readme.md create mode 100644 charts/speedscale/speedscale-operator/2.2.467/questions.yaml create mode 100644 charts/speedscale/speedscale-operator/2.2.467/templates/NOTES.txt create mode 100644 charts/speedscale/speedscale-operator/2.2.467/templates/admission.yaml create mode 100644 charts/speedscale/speedscale-operator/2.2.467/templates/configmap.yaml create mode 100644 charts/speedscale/speedscale-operator/2.2.467/templates/crds/trafficreplays.yaml create mode 100644 charts/speedscale/speedscale-operator/2.2.467/templates/deployments.yaml create mode 100644 charts/speedscale/speedscale-operator/2.2.467/templates/hooks.yaml create mode 100644 charts/speedscale/speedscale-operator/2.2.467/templates/rbac.yaml create mode 100644 charts/speedscale/speedscale-operator/2.2.467/templates/secrets.yaml create mode 100644 charts/speedscale/speedscale-operator/2.2.467/templates/services.yaml create mode 100644 charts/speedscale/speedscale-operator/2.2.467/templates/tls.yaml create mode 100644 charts/speedscale/speedscale-operator/2.2.467/values.yaml diff --git a/assets/codefresh/cf-runtime-6.4.1.tgz b/assets/codefresh/cf-runtime-6.4.1.tgz new file mode 100644 index 0000000000000000000000000000000000000000..1eb16850c5aa482947e22a9088814b99594ca2ef GIT binary patch literal 43721 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 W=i&JppZ^H}0RR7gTHQwg$_)Vb)Sxl| literal 0 HcmV?d00001 diff --git a/assets/speedscale/speedscale-operator-2.2.467.tgz b/assets/speedscale/speedscale-operator-2.2.467.tgz new file mode 100644 index 0000000000000000000000000000000000000000..93600e11b20b0278f1dadf6464539c5efff52d14 GIT binary patch literal 17059 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%0Ap8c3NFs2=-SR}P1E478L9Hx9GF!+3% zhACWXn#K((lUs;l)Bd@WB38M98DZ5MP$-zSoF@d?yMKzKoW_@W!GS4@wW`tz)*GAZ zsEc0NokN=f#>G(cqhvfF@w^O-0d}jCY;cpQdFube*ZAiW^inS}UHnmVASf$Wk2`1! zMljS48KJd;5p2nB>wq)Z1ppV5?()yj;9bhlHRGlmg1&lpo~o8_!zOt^GKK_NvpY6&$Ol%sqaXdw?dZGLA%`R8P$X3bjC^ z6vvk(EM2E7^*hkLR4_4pogUl_O)eSJB(2A{M{1C(*yY`*!dD{Vo3PSE$HI!P&Em?ikp5EkXLsfs;wU64()~1PC z$5;>)rEZsZO=bsE-e*iQfz727<`gm{_UJ=1.18-0' + catalog.cattle.io/release-name: cf-runtime +apiVersion: v2 +dependencies: +- name: cf-common + repository: file://./charts/cf-common + version: 0.16.0 +description: A Helm chart for Codefresh Runner +home: https://codefresh.io/ +icon: file://assets/icons/cf-runtime.png +keywords: +- codefresh +- runner +kubeVersion: '>=1.18-0' +maintainers: +- name: codefresh + url: https://codefresh-io.github.io/ +name: cf-runtime +sources: +- https://github.com/codefresh-io/venona +version: 6.4.1 diff --git a/charts/codefresh/cf-runtime/6.4.1/README.md b/charts/codefresh/cf-runtime/6.4.1/README.md new file mode 100644 index 0000000000..3bf6652d9d --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/README.md @@ -0,0 +1,1230 @@ +## Codefresh Runner + +![Version: 6.4.1](https://img.shields.io/badge/Version-6.4.1-informational?style=flat-square) + +Helm chart for deploying [Codefresh Runner](https://codefresh.io/docs/docs/installation/codefresh-runner/) to Kubernetes. + +## Table of Content + +- [Prerequisites](#prerequisites) +- [Get Chart Info](#get-chart-info) +- [Install Chart](#install-chart) +- [Chart Configuration](#chart-configuration) +- [Upgrade Chart](#upgrade-chart) + - [To 2.x](#to-2-x) + - [To 3.x](#to-3-x) + - [To 4.x](#to-4-x) + - [To 5.x](#to-5-x) + - [To 6.x](#to-6-x) +- [Architecture](#architecture) +- [Configuration](#configuration) + - [EBS backend volume configuration in AWS](#ebs-backend-volume-configuration) + - [Azure Disks backend volume configuration in AKS](#azure-disks-backend-volume-configuration) + - [GCE Disks backend volume configuration in GKE](#gce-disks-backend-volume-configuration-in-gke) + - [Custom volume mounts](#custom-volume-mounts) + - [Custom global environment variables](#custom-global-environment-variables) + - [Volume reuse policy](#volume-reuse-policy) + - [Volume cleaners](#volume-cleaners) + - [Rootless DinD](#rootless-dind) + - [ARM](#arm) + - [Openshift](#openshift) + - [On-premise](#on-premise) + +## Prerequisites + +- Kubernetes **1.19+** +- Helm **3.8.0+** + +⚠️⚠️⚠️ +> Since version 6.2.x chart is pushed **only** to OCI registry at `oci://quay.io/codefresh/cf-runtime` + +> Versions prior to 6.2.x are still available in ChartMuseum at `http://chartmuseum.codefresh.io/cf-runtime` + +## Get Chart Info + +```console +helm show all oci://quay.io/codefresh/cf-runtime +``` +See [Use OCI-based registries](https://helm.sh/docs/topics/registries/) + +## Install Chart + +**Important:** only helm3 is supported + +- Specify the following mandatory values + +`values.yaml` +```yaml +# -- Global parameters +# @default -- See below +global: + # -- User token in plain text (required if `global.codefreshTokenSecretKeyRef` is omitted!) + # Ref: https://g.codefresh.io/user/settings (see API Keys) + # Minimal API key scopes: Runner-Installation(read+write), Agent(read+write), Agents(read+write) + codefreshToken: "" + # -- User token that references an existing secret containing API key (required if `global.codefreshToken` is omitted!) + codefreshTokenSecretKeyRef: {} + # E.g. + # codefreshTokenSecretKeyRef: + # name: my-codefresh-api-token + # key: codefresh-api-token + + # -- Account ID (required!) + # Can be obtained here https://g.codefresh.io/2.0/account-settings/account-information + accountId: "" + + # -- K8s context name (required!) + context: "" + # E.g. + # context: prod-ue1-runtime-1 + + # -- Agent Name (optional!) + # If omitted, the following format will be used '{{ .Values.global.context }}_{{ .Release.Namespace }}' + agentName: "" + # E.g. + # agentName: prod-ue1-runtime-1 + + # -- Runtime name (optional!) + # If omitted, the following format will be used '{{ .Values.global.context }}/{{ .Release.Namespace }}' + runtimeName: "" + # E.g. + # runtimeName: prod-ue1-runtime-1/namespace +``` + +- Install chart + +```console +helm upgrade --install cf-runtime oci://quay.io/codefresh/cf-runtime -f values.yaml --create-namespace --namespace codefresh +``` + +## Chart Configuration + +See [Customizing the Chart Before Installing](https://helm.sh/docs/intro/using_helm/#customizing-the-chart-before-installing). + +## Upgrade Chart + +### To 2.x + +This major release renames and deprecated several values in the chart. Most of the workload templates have been refactored. + +Affected values: +- `dockerRegistry` is deprecated. Replaced with `global.imageRegistry` +- `re` is renamed to `runtime` +- `storage.localVolumeMonitor` is replaced with `volumeProvisioner.dind-lv-monitor` +- `volumeProvisioner.volume-cleanup` is replaced with `volumeProvisioner.dind-volume-cleanup` +- `image` values structure has been updated. Split to `image.registry` `image.repository` `image.tag` +- pod's `annotations` is renamed to `podAnnotations` + +### To 3.x + +⚠️⚠️⚠️ +### READ this before the upgrade! + +This major release adds [runtime-environment](https://codefresh.io/docs/docs/installation/codefresh-runner/#runtime-environment-specification) spec into chart templates. +That means it is possible to set parametes for `dind` and `engine` pods via [values.yaml](./values.yaml). + +**If you had any overrides (i.e. tolerations/nodeSelector/environment variables/etc) added in runtime spec via [codefresh CLI](https://codefresh-io.github.io/cli/) (for example, you did use [get](https://codefresh-io.github.io/cli/runtime-environments/get-runtime-environments/) and [patch](https://codefresh-io.github.io/cli/runtime-environments/apply-runtime-environments/) commands to modify the runtime-environment), you MUST add these into chart's [values.yaml](./values.yaml) for `.Values.runtime.dind` or(and) .`Values.runtime.engine`** + +**For backward compatibility, you can disable updating runtime-environment spec via** `.Values.runtime.patch.enabled=false` + +Affected values: +- added **mandatory** `global.codefreshToken`/`global.codefreshTokenSecretKeyRef` **You must specify it before the upgrade!** +- `runtime.engine` is added +- `runtime.dind` is added +- `global.existingAgentToken` is replaced with `global.agentTokenSecretKeyRef` +- `global.existingDindCertsSecret` is replaced with `global.dindCertsSecretRef` + +### To 4.x + +This major release adds **agentless inCluster** runtime mode (relevant only for [Codefresh On-Premises](#on-premise) users) + +Affected values: +- `runtime.agent` / `runtime.inCluster` / `runtime.accounts` / `runtime.description` are added + +### To 5.x + +This major release converts `.runtime.dind.pvcs` from **list** to **dict** + +> 4.x chart's values example: +```yaml +runtime: + dind: + pvcs: + - name: dind + storageClassName: my-storage-class-name + volumeSize: 32Gi + reuseVolumeSelector: 'codefresh-app,io.codefresh.accountName' + reuseVolumeSortOrder: pipeline_id +``` + +> 5.x chart's values example: +```yaml +runtime: + dind: + pvcs: + dind: + name: dind + storageClassName: my-storage-class-name + volumeSize: 32Gi + reuseVolumeSelector: 'codefresh-app,io.codefresh.accountName' + reuseVolumeSortOrder: pipeline_id +``` + +Affected values: +- `.runtime.dind.pvcs` converted from **list** to **dict** + +### To 6.x + +⚠️⚠️⚠️ +### READ this before the upgrade! + +This major release deprecates previously required `codefresh runner init --generate-helm-values-file`. + +Affected values: +- **Replaced** `.monitor.clusterId` with `.global.context` as **mandatory** value! +- **Deprecated** `.global.agentToken` / `.global.agentTokenSecretKeyRef` +- **Removed** `.global.agentId` +- **Removed** `.global.keys` / `.global.dindCertsSecretRef` +- **Removed** `.global.existingAgentToken` / `existingDindCertsSecret` +- **Removed** `.monitor.clusterId` / `.monitor.token` / `.monitor.existingMonitorToken` + +#### Migrate the Helm chart from version 5.x to 6.x + +Given this is the legacy `generated_values.yaml` values: + +> legacy `generated_values.yaml` +```yaml +{ + "appProxy": { + "enabled": false, + }, + "monitor": { + "enabled": false, + "clusterId": "my-cluster-name", + "token": "1234567890" + }, + "global": { + "namespace": "namespace", + "codefreshHost": "https://g.codefresh.io", + "agentToken": "0987654321", + "agentId": "agent-id-here", + "agentName": "my-cluster-name_my-namespace", + "accountId": "my-account-id", + "runtimeName": "my-cluster-name/my-namespace", + "codefreshToken": "1234567890", + "keys": { + "key": "-----BEGIN RSA PRIVATE KEY-----...", + "csr": "-----BEGIN CERTIFICATE REQUEST-----...", + "ca": "-----BEGIN CERTIFICATE-----...", + "serverCert": "-----BEGIN CERTIFICATE-----..." + } + } +} +``` + +Update `values.yaml` for new chart version: + +> For existing installation for backward compatibility `.Values.global.agentToken/agentTokenSecretKeyRef` **must be provided!** For installation from scratch this value is no longer required. + +> updated `values.yaml` +```yaml +global: + codefreshToken: "1234567890" + accountId: "my-account-id" + context: "my-cluster-name" + agentToken: "0987654321" # MANDATORY when migrating from < 6.x chart version ! + agentName: "my-cluster-name_my-namespace" # optional + runtimeName: "my-cluster-name/my-namespace" # optional +``` + +> **Note!** Though it's still possible to update runtime-environment via [get](https://codefresh-io.github.io/cli/runtime-environments/get-runtime-environments/) and [patch](https://codefresh-io.github.io/cli/runtime-environments/apply-runtime-environments/) commands, it's recommended to enable sidecar container to pull runtime spec from Codefresh API to detect any drift in configuration. + +```yaml +runner: + # -- Sidecar container + # Reconciles runtime spec from Codefresh API for drift detection + sidecar: + enabled: true +``` + +## Architecture + +[Codefresh Runner architecture](https://codefresh.io/docs/docs/installation/codefresh-runner/#codefresh-runner-architecture) + +## Configuration + +See [Customizing the Chart Before Installing](https://helm.sh/docs/intro/using_helm/#customizing-the-chart-before-installing). + +### EBS backend volume configuration + +`dind-volume-provisioner` should have permissions to create/attach/detach/delete/get EBS volumes + +Minimal IAM policy for `dind-volume-provisioner` + +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "ec2:AttachVolume", + "ec2:CreateSnapshot", + "ec2:CreateTags", + "ec2:CreateVolume", + "ec2:DeleteSnapshot", + "ec2:DeleteTags", + "ec2:DeleteVolume", + "ec2:DescribeInstances", + "ec2:DescribeSnapshots", + "ec2:DescribeTags", + "ec2:DescribeVolumes", + "ec2:DetachVolume" + ], + "Resource": "*" + } + ] +} +``` + +There are three options: + +1. Run `dind-volume-provisioner` pod on the node/node-group with IAM role + +```yaml +storage: + # -- Set backend volume type (`local`/`ebs`/`ebs-csi`/`gcedisk`/`azuredisk`) + backend: ebs-csi + + ebs: + availabilityZone: "us-east-1a" + +volumeProvisioner: + # -- Set node selector + nodeSelector: {} + # -- Set tolerations + tolerations: [] +``` + +2. Pass static credentials in `.Values.storage.ebs.accessKeyId/accessKeyIdSecretKeyRef` and `.Values.storage.ebs.secretAccessKey/secretAccessKeySecretKeyRef` + +```yaml +storage: + # -- Set backend volume type (`local`/`ebs`/`ebs-csi`/`gcedisk`/`azuredisk`) + backend: ebs-csi + + ebs: + availabilityZone: "us-east-1a" + + # -- Set AWS_ACCESS_KEY_ID for volume-provisioner (optional) + accessKeyId: "" + # -- Existing secret containing AWS_ACCESS_KEY_ID. + accessKeyIdSecretKeyRef: {} + # E.g. + # accessKeyIdSecretKeyRef: + # name: + # key: + + # -- Set AWS_SECRET_ACCESS_KEY for volume-provisioner (optional) + secretAccessKey: "" + # -- Existing secret containing AWS_SECRET_ACCESS_KEY + secretAccessKeySecretKeyRef: {} + # E.g. + # secretAccessKeySecretKeyRef: + # name: + # key: +``` + +3. Assign IAM role to `dind-volume-provisioner` service account + +```yaml +storage: + # -- Set backend volume type (`local`/`ebs`/`ebs-csi`/`gcedisk`/`azuredisk`) + backend: ebs-csi + + ebs: + availabilityZone: "us-east-1a" + +volumeProvisioner: + # -- Service Account parameters + serviceAccount: + # -- Create service account + create: true + # -- Additional service account annotations + annotations: + eks.amazonaws.com/role-arn: "arn:aws:iam:::role/" +``` + +### Custom volume mounts + +You can add your own volumes and volume mounts in the runtime environment, so that all pipeline steps will have access to the same set of external files. + +```yaml +runtime: + dind: + userVolumes: + regctl-docker-registry: + name: regctl-docker-registry + secret: + items: + - key: .dockerconfigjson + path: config.json + secretName: regctl-docker-registry + optional: true + userVolumeMounts: + regctl-docker-registry: + name: regctl-docker-registry + mountPath: /home/appuser/.docker/ + readOnly: true + +``` + +### Azure Disks backend volume configuration + +`dind-volume-provisioner` should have permissions to create/delete/get Azure Disks + +Role definition for `dind-volume-provisioner` + +`dind-volume-provisioner-role.json` +```json +{ + "Name": "CodefreshDindVolumeProvisioner", + "Description": "Perform create/delete/get disks", + "IsCustom": true, + "Actions": [ + "Microsoft.Compute/disks/read", + "Microsoft.Compute/disks/write", + "Microsoft.Compute/disks/delete" + + ], + "AssignableScopes": ["/subscriptions/"] +} +``` + +When creating an AKS cluster in Azure there is the option to use a [managed identity](https://learn.microsoft.com/en-us/azure/aks/use-managed-identity) that is assigned to the kubelet. This identity is assigned to the underlying node pool in the AKS cluster and can then be used by the dind-volume-provisioner. + +```console +export ROLE_DEFINITIN_FILE=dind-volume-provisioner-role.json +export SUBSCRIPTION_ID=$(az account show --query "id" | xargs echo ) +export RESOURCE_GROUP= +export AKS_NAME= +export LOCATION=$(az aks show -g $RESOURCE_GROUP -n $AKS_NAME --query location | xargs echo) +export NODES_RESOURCE_GROUP=MC_${RESOURCE_GROUP}_${AKS_NAME}_${LOCATION} +export NODE_SERVICE_PRINCIPAL=$(az aks show -g $RESOURCE_GROUP -n $AKS_NAME --query identityProfile.kubeletidentity.objectId | xargs echo) + +az role definition create --role-definition @${ROLE_DEFINITIN_FILE} +az role assignment create --assignee $NODE_SERVICE_PRINCIPAL --scope /subscriptions/$SUBSCRIPTION_ID/resourceGroups/$NODES_RESOURCE_GROUP --role CodefreshDindVolumeProvisioner +``` + +Deploy Helm chart with the following values: + +`values.yaml` +```yaml +volumeProvisioner: + podSecurityContext: + enabled: true + runAsUser: 0 + runAsGroup: 0 + fsGroup: 0 + +storage: + backend: azuredisk + azuredisk: + availabilityZone: northeurope-1 # replace with your zone + resourceGroup: my-resource-group-name + + mountAzureJson: true + +runtime: + dind: + nodeSelector: + topology.kubernetes.io/zone: northeurope-1 +``` + +### GCE Disks backend volume configuration in GKE + +`dind-volume-provisioner` should have `ComputeEngine.StorageAdmin` permissions + +There are three options: + +1. Run `dind-volume-provisioner` pod on the node/node-group with IAM Service Account + +```yaml +storage: + # -- Set backend volume type (`local`/`ebs`/`ebs-csi`/`gcedisk`/`azuredisk`) + backend: gcedisk + + gcedisk: + # -- Set GCP volume backend type (`pd-ssd`/`pd-standard`) + volumeType: "pd-standard" + # -- Set GCP volume availability zone + availabilityZone: "us-central1-c" + +volumeProvisioner: + # -- Set node selector + nodeSelector: {} + # -- Set tolerations + tolerations: [] + +# -- Set runtime parameters +runtime: + # -- Parameters for DinD (docker-in-docker) pod + dind: + # -- Set node selector. + nodeSelector: + topology.kubernetes.io/zone: us-central1-c +``` + +2. Pass static credentials in `.Values.storage.gcedisk.serviceAccountJson` (inline) or `.Values.storage.gcedisk.serviceAccountJsonSecretKeyRef` (from your own secret) + +```yaml +storage: + # -- Set backend volume type (`local`/`ebs`/`ebs-csi`/`gcedisk`/`azuredisk`) + backend: gcedisk + + gcedisk: + # -- Set GCP volume backend type (`pd-ssd`/`pd-standard`) + volumeType: "`pd-standard" + # -- Set GCP volume availability zone + availabilityZone: "us-central1-c" + # -- Set Google SA JSON key for volume-provisioner (optional) + serviceAccountJson: | + { + "type": "service_account", + "project_id": "...", + "private_key_id": "...", + "private_key": "...", + "client_email": "...", + "client_id": "...", + "auth_uri": "...", + "token_uri": "...", + "auth_provider_x509_cert_url": "...", + "client_x509_cert_url": "..." + } + # -- Existing secret containing containing Google SA JSON key for volume-provisioner (optional) + serviceAccountJsonSecretKeyRef: {} + # E.g.: + # serviceAccountJsonSecretKeyRef: + # name: gce-service-account + # key: service-account.json + +# -- Set runtime parameters +runtime: + # -- Parameters for DinD (docker-in-docker) pod + dind: + # -- Set node selector. + nodeSelector: + topology.kubernetes.io/zone: us-central1-c +``` + +3. Assign IAM role to `dind-volume-provisioner` service account + +```yaml +storage: + # -- Set backend volume type (`local`/`ebs`/`ebs-csi`/`gcedisk`/`azuredisk`) + backend: gcedisk + + gcedisk: + # -- Set GCP volume backend type (`pd-ssd`/`pd-standard`) + volumeType: "`pd-standard" + # -- Set GCP volume availability zone + availabilityZone: "us-central1-c" + +volumeProvisioner: + # -- Service Account parameters + serviceAccount: + # -- Create service account + create: true + # -- Additional service account annotations + annotations: + iam.gke.io/gcp-service-account: @.iam.gserviceaccount.com + +# -- Set runtime parameters +runtime: + # -- Parameters for DinD (docker-in-docker) pod + dind: + # -- Set node selector. + nodeSelector: + topology.kubernetes.io/zone: us-central1-c +``` + +### Custom global environment variables + +You can add your own environment variables to the runtime environment. All pipeline steps have access to the global variables. + +```yaml +runtime: + engine: + userEnvVars: + - name: GITHUB_TOKEN + valueFrom: + secretKeyRef: + name: github-token + key: token +``` + +### Volume reuse policy + +Volume reuse behavior depends on the configuration for `reuseVolumeSelector` in the runtime environment spec. + +```yaml +runtime: + dind: + pvcs: + - name: dind + ... + reuseVolumeSelector: 'codefresh-app,io.codefresh.accountName' + reuseVolumeSortOrder: pipeline_id +``` + +The following options are available: +- `reuseVolumeSelector: 'codefresh-app,io.codefresh.accountName'` - PV can be used by ANY pipeline in the specified account (default). +Benefit: Fewer PVs, resulting in lower costs. Since any PV can be used by any pipeline, the cluster needs to maintain/reserve fewer PVs in its PV pool for Codefresh. +Downside: Since the PV can be used by any pipeline, the PVs could have assets and info from different pipelines, reducing the probability of cache. + +- `reuseVolumeSelector: 'codefresh-app,io.codefresh.accountName,project_id'` - PV can be used by ALL pipelines in your account, assigned to the same project. + +- `reuseVolumeSelector: 'codefresh-app,io.codefresh.accountName,pipeline_id'` - PV can be used only by a single pipeline. +Benefit: More probability of cache without “spam” from other pipelines. +Downside: More PVs to maintain and therefore higher costs. + +- `reuseVolumeSelector: 'codefresh-app,io.codefresh.accountName,pipeline_id,io.codefresh.branch_name'` - PV can be used only by single pipeline AND single branch. + +- `reuseVolumeSelector: 'codefresh-app,io.codefresh.accountName,pipeline_id,trigger'` - PV can be used only by single pipeline AND single trigger. + +### Volume cleaners + +Codefresh pipelines require disk space for: + * [Pipeline Shared Volume](https://codefresh.io/docs/docs/pipelines/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) (`/codefresh/volume`, implemented as [docker volume](https://docs.docker.com/storage/volumes/)) + * Docker containers, both running and stopped + * Docker images and cached layers + +Codefresh offers two options to manage disk space and prevent out-of-space errors: +* Use runtime cleaners on Docker images and volumes +* [Set the minimum disk space per pipeline build volume](https://codefresh.io/docs/docs/pipelines/pipelines/#set-minimum-disk-space-for-a-pipeline-build) + +To improve performance by using Docker cache, Codefresh `volume-provisioner` can provision previously used disks with Docker images and pipeline volumes from previously run builds. + +### Types of runtime volume cleaners + +Docker images and volumes must be cleaned on a regular basis. + +* [IN-DIND cleaner](https://github.com/codefresh-io/dind/tree/master/cleaner): Deletes extra Docker containers, volumes, and images in **DIND pod**. +* [External volume cleaner](https://github.com/codefresh-io/dind-volume-cleanup): Deletes unused **external** PVs (EBS, GCE/Azure disks). +* [Local volume cleaner](https://github.com/codefresh-io/dind-volume-utils/blob/master/local-volumes/lv-cleaner.sh): Deletes **local** volumes if node disk space is close to the threshold. + +### IN-DIND cleaner + +**Purpose:** Removes unneeded *docker containers, images, volumes* inside Kubernetes volume mounted on the DIND pod + +**How it runs:** Inside each DIND pod as script + +**Triggered by:** SIGTERM and also during the run when disk usage > 90% (configurable) + +**Configured by:** Environment Variables which can be set in Runtime Environment spec + +**Configuration/Logic:** [README.md](https://github.com/codefresh-io/dind/tree/master/cleaner#readme) + +Override `.Values.runtime.dind.env` if necessary (the following are **defaults**): + +```yaml +runtime: + dind: + env: + CLEAN_PERIOD_SECONDS: '21600' # launch clean if last clean was more than CLEAN_PERIOD_SECONDS seconds ago + CLEAN_PERIOD_BUILDS: '5' # launch clean if last clean was more CLEAN_PERIOD_BUILDS builds since last build + IMAGE_RETAIN_PERIOD: '14400' # do not delete docker images if they have events since current_timestamp - IMAGE_RETAIN_PERIOD + VOLUMES_RETAIN_PERIOD: '14400' # do not delete docker volumes if they have events since current_timestamp - VOLUMES_RETAIN_PERIOD + DISK_USAGE_THRESHOLD: '0.8' # launch clean based on current disk usage DISK_USAGE_THRESHOLD + INODES_USAGE_THRESHOLD: '0.8' # launch clean based on current inodes usage INODES_USAGE_THRESHOLD +``` + +### External volumes cleaner + +**Purpose:** Removes unused *kubernetes volumes and related backend volumes* + +**How it runs:** Runs as `dind-volume-cleanup` CronJob. Installed in case the Runner uses non-local volumes `.Values.storage.backend != local` + +**Triggered by:** CronJob every 10min (configurable) + +**Configuration:** + +Set `codefresh.io/volume-retention` for dinds' PVCs: + +```yaml +runtime: + dind: + pvcs: + dind: + ... + annotations: + codefresh.io/volume-retention: 7d +``` + +Or override environment variables for `dind-volume-cleanup` cronjob: + +```yaml +volumeProvisioner: + dind-volume-cleanup: + env: + RETENTION_DAYS: 7 # clean volumes that were last used more than `RETENTION_DAYS` (default is 4) ago +``` + +### Local volumes cleaner + +**Purpose:** Deletes local volumes when node disk space is close to the threshold + +**How it runs:** Runs as `dind-lv-monitor` DaemonSet. Installed in case the Runner uses local volumes `.Values.storage.backend == local` + +**Triggered by:** Disk space usage or inode usage that exceeds thresholds (configurable) + +**Configuration:** + +Override environment variables for `dind-lv-monitor` daemonset: + +```yaml +volumeProvisioner: + dind-lv-monitor: + env: + KB_USAGE_THRESHOLD: 60 # default 80 (percentage) + INODE_USAGE_THRESHOLD: 60 # default 80 +``` + +### Rootless DinD + +DinD pod runs a `priviliged` container with **rootfull** docker. +To run the docker daemon as non-root user (**rootless** mode), change dind image tag: + +`values.yaml` +```yaml +runtime: + dind: + image: + tag: rootless +``` + +### ARM + +With the Codefresh Runner, you can run native ARM64v8 builds. + +> **Note!** +> You cannot run both amd64 and arm64 images within the same pipeline. As one pipeline can map only to one runtime, you can run either amd64 or arm64 within the same pipeline. + +Provide `nodeSelector` and(or) `tolerations` for dind pods: + +`values.yaml` +```yaml +runtime: + dind: + nodeSelector: + arch: arm64 + tolerations: + - key: arch + operator: Equal + value: arm64 + effect: NoSchedule +``` + +### Openshift + +To install Codefresh Runner on OpenShift use the following `values.yaml` example + +```yaml +runner: + podSecurityContext: + enabled: false + +volumeProvisioner: + podSecurityContext: + enabled: false + env: + PRIVILEGED_CONTAINER: true + dind-lv-monitor: + containerSecurityContext: + enabled: true + privileged: true + volumePermissions: + enabled: true + securityContext: + privileged: true + runAsUser: auto +``` + +Grant `privileged` SCC to `cf-runtime-runner` and `cf-runtime-volume-provisioner` service accounts. + +```console +oc adm policy add-scc-to-user privileged system:serviceaccount:codefresh:cf-runtime-runner + +oc adm policy add-scc-to-user privileged system:serviceaccount:codefresh:cf-runtime-volume-provisioner +``` + +### On-premise + +If you have [Codefresh On-Premises](https://artifacthub.io/packages/helm/codefresh-onprem/codefresh) deployed, you can install Codefresh Runner in **agentless** mode. + +**What is agentless mode?** + +Agent (aka venona) is Runner component which responsible for calling Codefresh API to run builds and create dind/engine pods and pvc objects. Agent can only be assigned to a single account, thus you can't share one runtime across multiple accounts. However, with **agentless** mode it's possible to register the runtime as **system**-type runtime so it's registered on the platform level and can be assigned/shared across multiple accounts. + +**What are the prerequisites?** +- You have a running [Codefresh On-Premises](https://artifacthub.io/packages/helm/codefresh-onprem/codefresh) control-plane environment +- You have a Codefresh API token with platform **Admin** permissions scope + +### How to deploy agentless runtime when it's on the SAME k8s cluster as On-Premises control-plane environment? + +- Enable cluster-level permissions for cf-api (On-Premises control-plane component) + +> `values.yaml` for [Codefresh On-Premises](https://artifacthub.io/packages/helm/codefresh-onprem/codefresh) Helm chart +```yaml +cfapi: + ... + # -- Enable ClusterRole/ClusterRoleBinding + rbac: + namespaced: false +``` + +- Set the following values for Runner Helm chart + +`.Values.global.codefreshHost=...` \ +`.Values.global.codefreshToken=...` \ +`.Values.global.runtimeName=system/...` \ +`.Values.runtime.agent=false` \ +`.Values.runtime.inCluster=true` + +> `values.yaml` for [Codefresh Runner](https://artifacthub.io/packages/helm/codefresh-runner/cf-runtime) helm chart +```yaml +global: + # -- URL of Codefresh On-Premises Platform + codefreshHost: "https://myonprem.somedomain.com" + # -- User token in plain text with Admin permission scope + codefreshToken: "" + # -- User token that references an existing secret containing API key. + codefreshTokenSecretKeyRef: {} + # E.g. + # codefreshTokenSecretKeyRef: + # name: my-codefresh-api-token + # key: codefresh-api-token + + # -- Distinguished runtime name + # (for On-Premise only; mandatory!) Must be prefixed with "system/..." + runtimeName: "system/prod-ue1-some-cluster-name" + +# -- Set runtime parameters +runtime: + # -- (for On-Premise only; mandatory!) Disable agent + agent: false + # -- (for On-Premise only; optional) Set inCluster runtime (default: `true`) + # `inCluster=true` flag is set when Runtime and On-Premises control-plane are run on the same cluster + # `inCluster=false` flag is set when Runtime and On-Premises control-plane are on different clusters + inCluster: true + # -- (for On-Premise only; optional) Assign accounts to runtime (list of account ids; default is empty) + # Accounts can be assigned to the runtime in Codefresh UI later so you can kepp it empty. + accounts: [] + # -- Set parent runtime to inherit. + runtimeExtends: [] +``` + +- Install the chart + +```console +helm upgrade --install cf-runtime oci://quay.io/codefresh/cf-runtime -f values.yaml --create-namespace --namespace cf-runtime +``` + +- Verify the runtime and run test pipeline + +Go to [https:///admin/runtime-environments/system](https:///admin/runtime-environments/system) to check the runtime. Assign it to the required account(s). Run test pipeline on it. + +### How to deploy agentless runtime when it's on the DIFFERENT k8s cluster than On-Premises control-plane environment? + +In this case, it's required to mount runtime cluster's `KUBECONFIG` into On-Premises `cf-api` deployment + +- Create the neccessary RBAC resources + +> `values.yaml` for [Codefresh Runner](https://artifacthub.io/packages/helm/codefresh-runner/cf-runtime) helm chart +```yaml +extraResources: +- apiVersion: rbac.authorization.k8s.io/v1 + kind: Role + metadata: + name: codefresh-role + namespace: '{{ .Release.Namespace }}' + rules: + - apiGroups: [""] + resources: ["pods", "persistentvolumeclaims", "persistentvolumes"] + verbs: ["list", "watch", "get", "create", "patch", "delete"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots"] + verbs: ["list", "watch", "get", "create", "patch", "delete"] +- apiVersion: v1 + kind: ServiceAccount + metadata: + name: codefresh-runtime-user + namespace: '{{ .Release.Namespace }}' +- apiVersion: rbac.authorization.k8s.io/v1 + kind: RoleBinding + metadata: + name: codefresh-runtime-user + namespace: '{{ .Release.Namespace }}' + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: codefresh-role + subjects: + - kind: ServiceAccount + name: codefresh-runtime-user + namespace: '{{ .Release.Namespace }}' +- apiVersion: v1 + kind: Secret + metadata: + name: codefresh-runtime-user-token + namespace: '{{ .Release.Namespace }}' + annotations: + kubernetes.io/service-account.name: codefresh-runtime-user + type: kubernetes.io/service-account-token +``` + +- Set up the following environment variables to create a `KUBECONFIG` file + +```shell +NAMESPACE=cf-runtime +CLUSTER_NAME=prod-ue1-some-cluster-name +CURRENT_CONTEXT=$(kubectl config current-context) + +USER_TOKEN_VALUE=$(kubectl -n cf-runtime get secret/codefresh-runtime-user-token -o=go-template='{{.data.token}}' | base64 --decode) +CURRENT_CLUSTER=$(kubectl config view --raw -o=go-template='{{range .contexts}}{{if eq .name "'''${CURRENT_CONTEXT}'''"}}{{ index .context "cluster" }}{{end}}{{end}}') +CLUSTER_CA=$(kubectl config view --raw -o=go-template='{{range .clusters}}{{if eq .name "'''${CURRENT_CLUSTER}'''"}}"{{with index .cluster "certificate-authority-data" }}{{.}}{{end}}"{{ end }}{{ end }}') +CLUSTER_SERVER=$(kubectl config view --raw -o=go-template='{{range .clusters}}{{if eq .name "'''${CURRENT_CLUSTER}'''"}}{{ .cluster.server }}{{end}}{{ end }}') + +export -p USER_TOKEN_VALUE CURRENT_CONTEXT CURRENT_CLUSTER CLUSTER_CA CLUSTER_SERVER CLUSTER_NAME +``` + +- Create a kubeconfig file + +```console +cat << EOF > $CLUSTER_NAME-kubeconfig +apiVersion: v1 +kind: Config +current-context: ${CLUSTER_NAME} +contexts: +- name: ${CLUSTER_NAME} + context: + cluster: ${CLUSTER_NAME} + user: codefresh-runtime-user + namespace: ${NAMESPACE} +clusters: +- name: ${CLUSTER_NAME} + cluster: + certificate-authority-data: ${CLUSTER_CA} + server: ${CLUSTER_SERVER} +users: +- name: ${CLUSTER_NAME} + user: + token: ${USER_TOKEN_VALUE} +EOF +``` + +- **Switch context to On-Premises control-plane cluster**. Create k8s secret (via any tool like [ESO](https://external-secrets.io/v0.4.4/), `kubectl`, etc ) containing runtime cluster's `KUBECONFG` created in previous step. + +```shell +NAMESPACE=codefresh +kubectl create secret generic dind-runtime-clusters --from-file=$CLUSTER_NAME=$CLUSTER_NAME-kubeconfig -n $NAMESPACE +``` + +- Mount secret containing runtime cluster's `KUBECONFG` into cf-api in On-Premises control-plane cluster + +> `values.yaml` for [Codefresh On-Premises](https://artifacthub.io/packages/helm/codefresh-onprem/codefresh) helm chart +```yaml +cf-api: + ... + volumes: + dind-clusters: + enabled: true + type: secret + nameOverride: dind-runtime-clusters + optional: true +``` +> volumeMount `/etc/kubeconfig` is already configured in cf-api Helm chart template. No need to specify it. + +- Set the following values for Runner helm chart + +> `values.yaml` for [Codefresh Runner](https://artifacthub.io/packages/helm/codefresh-runner/cf-runtime) helm chart + +`.Values.global.codefreshHost=...` \ +`.Values.global.codefreshToken=...` \ +`.Values.global.runtimeName=system/...` \ +`.Values.runtime.agent=false` \ +`.Values.runtime.inCluster=false` + +**Important!** +`.Values.global.name` ("system/" prefix is ignored!) should match the cluster name (key in `dind-runtime-clusters` secret created previously) +```yaml +global: + # -- URL of Codefresh On-Premises Platform + codefreshHost: "https://myonprem.somedomain.com" + # -- User token in plain text with Admin permission scope + codefreshToken: "" + # -- User token that references an existing secret containing API key. + codefreshTokenSecretKeyRef: {} + # E.g. + # codefreshTokenSecretKeyRef: + # name: my-codefresh-api-token + # key: codefresh-api-token + + # -- Distinguished runtime name + # (for On-Premise only; mandatory!) Must be prefixed with "system/..." + name: "system/prod-ue1-some-cluster-name" + +# -- Set runtime parameters +runtime: + # -- (for On-Premise only; mandatory!) Disable agent + agent: false + # -- (for On-Premise only; optional) Set inCluster runtime (default: `true`) + # `inCluster=true` flag is set when Runtime and On-Premises control-plane are run on the same cluster + # `inCluster=false` flag is set when Runtime and On-Premises control-plane are on different clusters + inCluster: false + # -- (for On-Premise only; optional) Assign accounts to runtime (list of account ids; default is empty) + # Accounts can be assigned to the runtime in Codefresh UI later so you can kepp it empty. + accounts: [] + # -- (optional) Set parent runtime to inherit. + runtimeExtends: [] +``` + +- Install the chart + +```console +helm upgrade --install cf-runtime oci://quay.io/codefresh/cf-runtime -f values.yaml --create-namespace --namespace cf-runtime +``` + +- Verify the runtime and run test pipeline + +Go to [https:///admin/runtime-environments/system](https:///admin/runtime-environments/system) to see the runtime. Assign it to the required account(s). + +## Requirements + +| Repository | Name | Version | +|------------|------|---------| +| oci://quay.io/codefresh/charts | cf-common | 0.16.0 | + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| appProxy.affinity | object | `{}` | Set affinity | +| appProxy.enabled | bool | `false` | Enable app-proxy | +| appProxy.env | object | `{}` | Add additional env vars | +| appProxy.image | object | `{"registry":"quay.io","repository":"codefresh/cf-app-proxy","tag":"0.0.47"}` | Set image | +| appProxy.ingress.annotations | object | `{}` | Set extra annotations for ingress object | +| appProxy.ingress.class | string | `""` | Set ingress class | +| appProxy.ingress.host | string | `""` | Set DNS hostname the ingress will use | +| appProxy.ingress.pathPrefix | string | `""` | Set path prefix for ingress (keep empty for default `/` path) | +| appProxy.ingress.tlsSecret | string | `""` | Set k8s tls secret for the ingress object | +| appProxy.nodeSelector | object | `{}` | Set node selector | +| appProxy.podAnnotations | object | `{}` | Set pod annotations | +| appProxy.podSecurityContext | object | `{}` | Set security context for the pod | +| appProxy.rbac | object | `{"create":true,"namespaced":true,"rules":[]}` | RBAC parameters | +| appProxy.rbac.create | bool | `true` | Create RBAC resources | +| appProxy.rbac.namespaced | bool | `true` | Use Role(true)/ClusterRole(true) | +| appProxy.rbac.rules | list | `[]` | Add custom rule to the role | +| appProxy.readinessProbe | object | See below | Readiness probe configuration | +| appProxy.replicasCount | int | `1` | Set number of pods | +| appProxy.resources | object | `{}` | Set requests and limits | +| appProxy.serviceAccount | object | `{"annotations":{},"create":true,"name":"","namespaced":true}` | Service Account parameters | +| appProxy.serviceAccount.annotations | object | `{}` | Additional service account annotations | +| appProxy.serviceAccount.create | bool | `true` | Create service account | +| appProxy.serviceAccount.name | string | `""` | Override service account name | +| appProxy.serviceAccount.namespaced | bool | `true` | Use Role(true)/ClusterRole(true) | +| appProxy.tolerations | list | `[]` | Set tolerations | +| appProxy.updateStrategy | object | `{"type":"RollingUpdate"}` | Upgrade strategy | +| dockerRegistry | string | `""` | | +| event-exporter | object | See below | Event exporter parameters | +| event-exporter.affinity | object | `{}` | Set affinity | +| event-exporter.enabled | bool | `false` | Enable event-exporter | +| event-exporter.env | object | `{}` | Add additional env vars | +| event-exporter.image | object | `{"registry":"docker.io","repository":"codefresh/k8s-event-exporter","tag":"latest"}` | Set image | +| event-exporter.nodeSelector | object | `{}` | Set node selector | +| event-exporter.podAnnotations | object | `{}` | Set pod annotations | +| event-exporter.podSecurityContext | object | See below | Set security context for the pod | +| event-exporter.rbac | object | `{"create":true,"rules":[]}` | RBAC parameters | +| event-exporter.rbac.create | bool | `true` | Create RBAC resources | +| event-exporter.rbac.rules | list | `[]` | Add custom rule to the role | +| event-exporter.replicasCount | int | `1` | Set number of pods | +| event-exporter.resources | object | `{}` | Set resources | +| event-exporter.serviceAccount | object | `{"annotations":{},"create":true,"name":""}` | Service Account parameters | +| event-exporter.serviceAccount.annotations | object | `{}` | Additional service account annotations | +| event-exporter.serviceAccount.create | bool | `true` | Create service account | +| event-exporter.serviceAccount.name | string | `""` | Override service account name | +| event-exporter.tolerations | list | `[]` | Set tolerations | +| event-exporter.updateStrategy | object | `{"type":"Recreate"}` | Upgrade strategy | +| extraResources | list | `[]` | Array of extra objects to deploy with the release | +| fullnameOverride | string | `""` | String to fully override cf-runtime.fullname template | +| global | object | See below | Global parameters | +| global.accountId | string | `""` | Account ID (required!) Can be obtained here https://g.codefresh.io/2.0/account-settings/account-information | +| global.agentName | string | `""` | Agent Name (optional!) If omitted, the following format will be used `{{ .Values.global.context }}_{{ .Release.Namespace }}` | +| global.agentToken | string | `""` | DEPRECATED Agent token in plain text. !!! MUST BE provided if migrating from < 6.x chart version | +| global.agentTokenSecretKeyRef | object | `{}` | DEPRECATED Agent token that references an existing secret containing API key. !!! MUST BE provided if migrating from < 6.x chart version | +| global.codefreshHost | string | `"https://g.codefresh.io"` | URL of Codefresh Platform (required!) | +| global.codefreshToken | string | `""` | User token in plain text (required if `global.codefreshTokenSecretKeyRef` is omitted!) Ref: https://g.codefresh.io/user/settings (see API Keys) Minimal API key scopes: Runner-Installation(read+write), Agent(read+write), Agents(read+write) | +| global.codefreshTokenSecretKeyRef | object | `{}` | User token that references an existing secret containing API key (required if `global.codefreshToken` is omitted!) | +| global.context | string | `""` | K8s context name (required!) | +| global.imagePullSecrets | list | `[]` | Global Docker registry secret names as array | +| global.imageRegistry | string | `""` | Global Docker image registry | +| global.runtimeName | string | `""` | Runtime name (optional!) If omitted, the following format will be used `{{ .Values.global.context }}/{{ .Release.Namespace }}` | +| monitor.affinity | object | `{}` | Set affinity | +| monitor.enabled | bool | `false` | Enable monitor Ref: https://codefresh.io/docs/docs/installation/codefresh-runner/#install-monitoring-component | +| monitor.env | object | `{}` | Add additional env vars | +| monitor.image | object | `{"registry":"quay.io","repository":"codefresh/cf-k8s-agent","tag":"1.3.18"}` | Set image | +| monitor.nodeSelector | object | `{}` | Set node selector | +| monitor.podAnnotations | object | `{}` | Set pod annotations | +| monitor.podSecurityContext | object | `{}` | | +| monitor.rbac | object | `{"create":true,"namespaced":true,"rules":[]}` | RBAC parameters | +| monitor.rbac.create | bool | `true` | Create RBAC resources | +| monitor.rbac.namespaced | bool | `true` | Use Role(true)/ClusterRole(true) | +| monitor.rbac.rules | list | `[]` | Add custom rule to the role | +| monitor.readinessProbe | object | See below | Readiness probe configuration | +| monitor.replicasCount | int | `1` | Set number of pods | +| monitor.resources | object | `{}` | Set resources | +| monitor.serviceAccount | object | `{"annotations":{},"create":true,"name":""}` | Service Account parameters | +| monitor.serviceAccount.annotations | object | `{}` | Additional service account annotations | +| monitor.serviceAccount.create | bool | `true` | Create service account | +| monitor.serviceAccount.name | string | `""` | Override service account name | +| monitor.tolerations | list | `[]` | Set tolerations | +| monitor.updateStrategy | object | `{"type":"RollingUpdate"}` | Upgrade strategy | +| nameOverride | string | `""` | String to partially override cf-runtime.fullname template (will maintain the release name) | +| podMonitor | object | See below | Add podMonitor (for engine pods) | +| podMonitor.main.enabled | bool | `false` | Enable pod monitor for engine pods | +| podMonitor.runner.enabled | bool | `false` | Enable pod monitor for runner pod | +| podMonitor.volume-provisioner.enabled | bool | `false` | Enable pod monitor for volumeProvisioner pod | +| re | object | `{}` | | +| runner | object | See below | Runner parameters | +| runner.affinity | object | `{}` | Set affinity | +| runner.enabled | bool | `true` | Enable the runner | +| runner.env | object | `{}` | Add additional env vars | +| runner.image | object | `{"registry":"quay.io","repository":"codefresh/venona","tag":"1.10.2"}` | Set image | +| runner.init | object | `{"image":{"registry":"quay.io","repository":"codefresh/cli","tag":"0.85.0-rootless"},"resources":{"limits":{"cpu":"1","memory":"512Mi"},"requests":{"cpu":"0.2","memory":"256Mi"}}}` | Init container | +| runner.nodeSelector | object | `{}` | Set node selector | +| runner.podAnnotations | object | `{}` | Set pod annotations | +| runner.podSecurityContext | object | See below | Set security context for the pod | +| runner.rbac | object | `{"create":true,"rules":[]}` | RBAC parameters | +| runner.rbac.create | bool | `true` | Create RBAC resources | +| runner.rbac.rules | list | `[]` | Add custom rule to the role | +| runner.readinessProbe | object | See below | Readiness probe configuration | +| runner.replicasCount | int | `1` | Set number of pods | +| runner.resources | object | `{}` | Set requests and limits | +| runner.serviceAccount | object | `{"annotations":{},"create":true,"name":""}` | Service Account parameters | +| runner.serviceAccount.annotations | object | `{}` | Additional service account annotations | +| runner.serviceAccount.create | bool | `true` | Create service account | +| runner.serviceAccount.name | string | `""` | Override service account name | +| runner.sidecar | object | `{"enabled":false,"env":{"RECONCILE_INTERVAL":300},"image":{"registry":"quay.io","repository":"codefresh/codefresh-shell","tag":"0.0.2"},"resources":{}}` | Sidecar container Reconciles runtime spec from Codefresh API for drift detection | +| runner.tolerations | list | `[]` | Set tolerations | +| runner.updateStrategy | object | `{"type":"RollingUpdate"}` | Upgrade strategy | +| runtime | object | See below | Set runtime parameters | +| runtime.accounts | list | `[]` | (for On-Premise only) Assign accounts to runtime (list of account ids) | +| runtime.agent | bool | `true` | (for On-Premise only) Enable agent | +| runtime.description | string | `""` | Runtime description | +| runtime.dind | object | `{"affinity":{},"env":{"DOCKER_ENABLE_DEPRECATED_PULL_SCHEMA_1_IMAGE":true},"image":{"pullPolicy":"IfNotPresent","registry":"quay.io","repository":"codefresh/dind","tag":"26.1.4-1.28.7"},"nodeSelector":{},"podAnnotations":{},"podLabels":{},"pvcs":{"dind":{"annotations":{},"name":"dind","reuseVolumeSelector":"codefresh-app,io.codefresh.accountName","reuseVolumeSortOrder":"pipeline_id","storageClassName":"{{ include \"dind-volume-provisioner.storageClassName\" . }}","volumeSize":"16Gi"}},"resources":{"limits":{"cpu":"400m","memory":"800Mi"},"requests":null},"schedulerName":"","serviceAccount":"codefresh-engine","terminationGracePeriodSeconds":30,"tolerations":[],"userAccess":true,"userVolumeMounts":{},"userVolumes":{}}` | Parameters for DinD (docker-in-docker) pod (aka "runtime" pod). | +| runtime.dind.affinity | object | `{}` | Set affinity | +| runtime.dind.env | object | `{"DOCKER_ENABLE_DEPRECATED_PULL_SCHEMA_1_IMAGE":true}` | Set additional env vars. | +| runtime.dind.image | object | `{"pullPolicy":"IfNotPresent","registry":"quay.io","repository":"codefresh/dind","tag":"26.1.4-1.28.7"}` | Set dind image. | +| runtime.dind.nodeSelector | object | `{}` | Set node selector. | +| runtime.dind.podAnnotations | object | `{}` | Set pod annotations. | +| runtime.dind.podLabels | object | `{}` | Set pod labels. | +| runtime.dind.pvcs | object | `{"dind":{"annotations":{},"name":"dind","reuseVolumeSelector":"codefresh-app,io.codefresh.accountName","reuseVolumeSortOrder":"pipeline_id","storageClassName":"{{ include \"dind-volume-provisioner.storageClassName\" . }}","volumeSize":"16Gi"}}` | PV claim spec parametes. | +| runtime.dind.pvcs.dind | object | `{"annotations":{},"name":"dind","reuseVolumeSelector":"codefresh-app,io.codefresh.accountName","reuseVolumeSortOrder":"pipeline_id","storageClassName":"{{ include \"dind-volume-provisioner.storageClassName\" . }}","volumeSize":"16Gi"}` | Default dind PVC parameters | +| runtime.dind.pvcs.dind.annotations | object | `{}` | PV annotations. | +| runtime.dind.pvcs.dind.name | string | `"dind"` | PVC name prefix. Keep `dind` as default! Don't change! | +| runtime.dind.pvcs.dind.reuseVolumeSelector | string | `"codefresh-app,io.codefresh.accountName"` | PV reuse selector. Ref: https://codefresh.io/docs/docs/installation/codefresh-runner/#volume-reuse-policy | +| runtime.dind.pvcs.dind.storageClassName | string | `"{{ include \"dind-volume-provisioner.storageClassName\" . }}"` | PVC storage class name. Change ONLY if you need to use storage class NOT from Codefresh volume-provisioner | +| runtime.dind.pvcs.dind.volumeSize | string | `"16Gi"` | PVC size. | +| runtime.dind.resources | object | `{"limits":{"cpu":"400m","memory":"800Mi"},"requests":null}` | Set dind resources. | +| runtime.dind.schedulerName | string | `""` | Set scheduler name. | +| runtime.dind.serviceAccount | string | `"codefresh-engine"` | Set service account for pod. | +| runtime.dind.terminationGracePeriodSeconds | int | `30` | Set termination grace period. | +| runtime.dind.tolerations | list | `[]` | Set tolerations. | +| runtime.dind.userAccess | bool | `true` | Keep `true` as default! | +| runtime.dind.userVolumeMounts | object | `{}` | Add extra volume mounts | +| runtime.dind.userVolumes | object | `{}` | Add extra volumes | +| runtime.dindDaemon | object | See below | DinD pod daemon config | +| runtime.engine | object | `{"affinity":{},"command":["npm","run","start"],"env":{"CONTAINER_LOGGER_EXEC_CHECK_INTERVAL_MS":1000,"DOCKER_REQUEST_TIMEOUT_MS":30000,"FORCE_COMPOSE_SERIAL_PULL":false,"LOGGER_LEVEL":"debug","LOG_OUTGOING_HTTP_REQUESTS":false,"METRICS_PROMETHEUS_COLLECT_PROCESS_METRICS":false,"METRICS_PROMETHEUS_ENABLED":true,"METRICS_PROMETHEUS_ENABLE_LEGACY_METRICS":false,"METRICS_PROMETHEUS_HOST":"0.0.0.0","METRICS_PROMETHEUS_PORT":9100},"image":{"pullPolicy":"IfNotPresent","registry":"quay.io","repository":"codefresh/engine","tag":"1.174.12"},"nodeSelector":{},"podAnnotations":{},"podLabels":{},"resources":{"limits":{"cpu":"1000m","memory":"2048Mi"},"requests":{"cpu":"100m","memory":"128Mi"}},"runtimeImages":{"COMPOSE_IMAGE":"quay.io/codefresh/compose:v2.28.1-1.5.0","CONTAINER_LOGGER_IMAGE":"quay.io/codefresh/cf-container-logger:1.11.6","COSIGN_IMAGE_SIGNER_IMAGE":"quay.io/codefresh/cf-cosign-image-signer:2.4.0-cf.2","CR_6177_FIXER":"quay.io/codefresh/alpine:edge","DOCKER_BUILDER_IMAGE":"quay.io/codefresh/cf-docker-builder:1.3.13","DOCKER_PULLER_IMAGE":"quay.io/codefresh/cf-docker-puller:8.0.17","DOCKER_PUSHER_IMAGE":"quay.io/codefresh/cf-docker-pusher:6.0.16","DOCKER_TAG_PUSHER_IMAGE":"quay.io/codefresh/cf-docker-tag-pusher:1.3.14","FS_OPS_IMAGE":"quay.io/codefresh/fs-ops:1.2.3","GC_BUILDER_IMAGE":"quay.io/codefresh/cf-gc-builder:0.5.3","GIT_CLONE_IMAGE":"quay.io/codefresh/cf-git-cloner:10.1.28","KUBE_DEPLOY":"quay.io/codefresh/cf-deploy-kubernetes:16.1.11","PIPELINE_DEBUGGER_IMAGE":"quay.io/codefresh/cf-debugger:1.3.0","TEMPLATE_ENGINE":"quay.io/codefresh/pikolo:0.14.1"},"schedulerName":"","serviceAccount":"codefresh-engine","terminationGracePeriodSeconds":180,"tolerations":[],"userEnvVars":[],"workflowLimits":{"MAXIMUM_ALLOWED_TIME_BEFORE_PRE_STEPS_SUCCESS":600,"MAXIMUM_ALLOWED_WORKFLOW_AGE_BEFORE_TERMINATION":86400,"MAXIMUM_ELECTED_STATE_AGE_ALLOWED":900,"MAXIMUM_RETRY_ATTEMPTS_ALLOWED":20,"MAXIMUM_TERMINATING_STATE_AGE_ALLOWED":900,"MAXIMUM_TERMINATING_STATE_AGE_ALLOWED_WITHOUT_UPDATE":300,"TIME_ENGINE_INACTIVE_UNTIL_TERMINATION":300,"TIME_ENGINE_INACTIVE_UNTIL_UNHEALTHY":60,"TIME_INACTIVE_UNTIL_TERMINATION":2700}}` | Parameters for Engine pod (aka "pipeline" orchestrator). | +| runtime.engine.affinity | object | `{}` | Set affinity | +| runtime.engine.command | list | `["npm","run","start"]` | Set container command. | +| runtime.engine.env | object | `{"CONTAINER_LOGGER_EXEC_CHECK_INTERVAL_MS":1000,"DOCKER_REQUEST_TIMEOUT_MS":30000,"FORCE_COMPOSE_SERIAL_PULL":false,"LOGGER_LEVEL":"debug","LOG_OUTGOING_HTTP_REQUESTS":false,"METRICS_PROMETHEUS_COLLECT_PROCESS_METRICS":false,"METRICS_PROMETHEUS_ENABLED":true,"METRICS_PROMETHEUS_ENABLE_LEGACY_METRICS":false,"METRICS_PROMETHEUS_HOST":"0.0.0.0","METRICS_PROMETHEUS_PORT":9100}` | Set additional env vars. | +| runtime.engine.env.CONTAINER_LOGGER_EXEC_CHECK_INTERVAL_MS | int | `1000` | Interval to check the exec status in the container-logger | +| runtime.engine.env.DOCKER_REQUEST_TIMEOUT_MS | int | `30000` | Timeout while doing requests to the Docker daemon | +| runtime.engine.env.FORCE_COMPOSE_SERIAL_PULL | bool | `false` | If "true", composition images will be pulled sequentially | +| runtime.engine.env.LOGGER_LEVEL | string | `"debug"` | Level of logging for engine | +| runtime.engine.env.LOG_OUTGOING_HTTP_REQUESTS | bool | `false` | Enable debug-level logging of outgoing HTTP/HTTPS requests | +| runtime.engine.env.METRICS_PROMETHEUS_COLLECT_PROCESS_METRICS | bool | `false` | Enable collecting process metrics | +| runtime.engine.env.METRICS_PROMETHEUS_ENABLED | bool | `true` | Enable emitting metrics from engine | +| runtime.engine.env.METRICS_PROMETHEUS_ENABLE_LEGACY_METRICS | bool | `false` | Enable legacy metrics | +| runtime.engine.env.METRICS_PROMETHEUS_HOST | string | `"0.0.0.0"` | Host for Prometheus metrics server | +| runtime.engine.env.METRICS_PROMETHEUS_PORT | int | `9100` | Port for Prometheus metrics server | +| runtime.engine.image | object | `{"pullPolicy":"IfNotPresent","registry":"quay.io","repository":"codefresh/engine","tag":"1.174.12"}` | Set image. | +| runtime.engine.nodeSelector | object | `{}` | Set node selector. | +| runtime.engine.podAnnotations | object | `{}` | Set pod annotations. | +| runtime.engine.podLabels | object | `{}` | Set pod labels. | +| runtime.engine.resources | object | `{"limits":{"cpu":"1000m","memory":"2048Mi"},"requests":{"cpu":"100m","memory":"128Mi"}}` | Set resources. | +| runtime.engine.runtimeImages | object | See below. | Set system(base) runtime images. | +| runtime.engine.schedulerName | string | `""` | Set scheduler name. | +| runtime.engine.serviceAccount | string | `"codefresh-engine"` | Set service account for pod. | +| runtime.engine.terminationGracePeriodSeconds | int | `180` | Set termination grace period. | +| runtime.engine.tolerations | list | `[]` | Set tolerations. | +| runtime.engine.userEnvVars | list | `[]` | Set extra env vars | +| runtime.engine.workflowLimits | object | `{"MAXIMUM_ALLOWED_TIME_BEFORE_PRE_STEPS_SUCCESS":600,"MAXIMUM_ALLOWED_WORKFLOW_AGE_BEFORE_TERMINATION":86400,"MAXIMUM_ELECTED_STATE_AGE_ALLOWED":900,"MAXIMUM_RETRY_ATTEMPTS_ALLOWED":20,"MAXIMUM_TERMINATING_STATE_AGE_ALLOWED":900,"MAXIMUM_TERMINATING_STATE_AGE_ALLOWED_WITHOUT_UPDATE":300,"TIME_ENGINE_INACTIVE_UNTIL_TERMINATION":300,"TIME_ENGINE_INACTIVE_UNTIL_UNHEALTHY":60,"TIME_INACTIVE_UNTIL_TERMINATION":2700}` | Set workflow limits. | +| runtime.engine.workflowLimits.MAXIMUM_ALLOWED_TIME_BEFORE_PRE_STEPS_SUCCESS | int | `600` | Maximum time allowed to the engine to wait for the pre-steps (aka "Initializing Process") to succeed; seconds. | +| runtime.engine.workflowLimits.MAXIMUM_ALLOWED_WORKFLOW_AGE_BEFORE_TERMINATION | int | `86400` | Maximum time for workflow execution; seconds. | +| runtime.engine.workflowLimits.MAXIMUM_ELECTED_STATE_AGE_ALLOWED | int | `900` | Maximum time allowed to workflow to spend in "elected" state; seconds. | +| runtime.engine.workflowLimits.MAXIMUM_RETRY_ATTEMPTS_ALLOWED | int | `20` | Maximum retry attempts allowed for workflow. | +| runtime.engine.workflowLimits.MAXIMUM_TERMINATING_STATE_AGE_ALLOWED | int | `900` | Maximum time allowed to workflow to spend in "terminating" state until force terminated; seconds. | +| runtime.engine.workflowLimits.MAXIMUM_TERMINATING_STATE_AGE_ALLOWED_WITHOUT_UPDATE | int | `300` | Maximum time allowed to workflow to spend in "terminating" state without logs activity until force terminated; seconds. | +| runtime.engine.workflowLimits.TIME_ENGINE_INACTIVE_UNTIL_TERMINATION | int | `300` | Time since the last health check report after which workflow is terminated; seconds. | +| runtime.engine.workflowLimits.TIME_ENGINE_INACTIVE_UNTIL_UNHEALTHY | int | `60` | Time since the last health check report after which the engine is considered unhealthy; seconds. | +| runtime.engine.workflowLimits.TIME_INACTIVE_UNTIL_TERMINATION | int | `2700` | Time since the last workflow logs activity after which workflow is terminated; seconds. | +| runtime.gencerts | object | See below | Parameters for `gencerts-dind` post-upgrade/install hook | +| runtime.inCluster | bool | `true` | (for On-Premise only) Set inCluster runtime | +| runtime.patch | object | See below | Parameters for `runtime-patch` post-upgrade/install hook | +| runtime.rbac | object | `{"create":true,"rules":[]}` | RBAC parameters | +| runtime.rbac.create | bool | `true` | Create RBAC resources | +| runtime.rbac.rules | list | `[]` | Add custom rule to the engine role | +| runtime.runtimeExtends | list | `["system/default/hybrid/k8s_low_limits"]` | Set parent runtime to inherit. Should not be changes. Parent runtime is controlled from Codefresh side. | +| runtime.serviceAccount | object | `{"annotations":{},"create":true}` | Set annotation on engine Service Account Ref: https://codefresh.io/docs/docs/administration/codefresh-runner/#injecting-aws-arn-roles-into-the-cluster | +| serviceMonitor | object | See below | Add serviceMonitor | +| serviceMonitor.main.enabled | bool | `false` | Enable service monitor for dind pods | +| storage.azuredisk.cachingMode | string | `"None"` | | +| storage.azuredisk.skuName | string | `"Premium_LRS"` | Set storage type (`Premium_LRS`) | +| storage.backend | string | `"local"` | Set backend volume type (`local`/`ebs`/`ebs-csi`/`gcedisk`/`azuredisk`) | +| storage.ebs.accessKeyId | string | `""` | Set AWS_ACCESS_KEY_ID for volume-provisioner (optional) Ref: https://codefresh.io/docs/docs/installation/codefresh-runner/#dind-volume-provisioner-permissions | +| storage.ebs.accessKeyIdSecretKeyRef | object | `{}` | Existing secret containing AWS_ACCESS_KEY_ID. | +| storage.ebs.availabilityZone | string | `"us-east-1a"` | Set EBS volumes availability zone (required) | +| storage.ebs.encrypted | string | `"false"` | Enable encryption (optional) | +| storage.ebs.kmsKeyId | string | `""` | Set KMS encryption key ID (optional) | +| storage.ebs.secretAccessKey | string | `""` | Set AWS_SECRET_ACCESS_KEY for volume-provisioner (optional) Ref: https://codefresh.io/docs/docs/installation/codefresh-runner/#dind-volume-provisioner-permissions | +| storage.ebs.secretAccessKeySecretKeyRef | object | `{}` | Existing secret containing AWS_SECRET_ACCESS_KEY | +| storage.ebs.volumeType | string | `"gp2"` | Set EBS volume type (`gp2`/`gp3`/`io1`) (required) | +| storage.fsType | string | `"ext4"` | Set filesystem type (`ext4`/`xfs`) | +| storage.gcedisk.availabilityZone | string | `"us-west1-a"` | Set GCP volume availability zone | +| storage.gcedisk.serviceAccountJson | string | `""` | Set Google SA JSON key for volume-provisioner (optional) | +| storage.gcedisk.serviceAccountJsonSecretKeyRef | object | `{}` | Existing secret containing containing Google SA JSON key for volume-provisioner (optional) | +| storage.gcedisk.volumeType | string | `"pd-ssd"` | Set GCP volume backend type (`pd-ssd`/`pd-standard`) | +| storage.local.volumeParentDir | string | `"/var/lib/codefresh/dind-volumes"` | Set volume path on the host filesystem | +| storage.mountAzureJson | bool | `false` | | +| volumeProvisioner | object | See below | Volume Provisioner parameters | +| volumeProvisioner.affinity | object | `{}` | Set affinity | +| volumeProvisioner.dind-lv-monitor | object | See below | `dind-lv-monitor` DaemonSet parameters (local volumes cleaner) | +| volumeProvisioner.enabled | bool | `true` | Enable volume-provisioner | +| volumeProvisioner.env | object | `{}` | Add additional env vars | +| volumeProvisioner.image | object | `{"registry":"quay.io","repository":"codefresh/dind-volume-provisioner","tag":"1.35.0"}` | Set image | +| volumeProvisioner.nodeSelector | object | `{}` | Set node selector | +| volumeProvisioner.podAnnotations | object | `{}` | Set pod annotations | +| volumeProvisioner.podSecurityContext | object | See below | Set security context for the pod | +| volumeProvisioner.rbac | object | `{"create":true,"rules":[]}` | RBAC parameters | +| volumeProvisioner.rbac.create | bool | `true` | Create RBAC resources | +| volumeProvisioner.rbac.rules | list | `[]` | Add custom rule to the role | +| volumeProvisioner.replicasCount | int | `1` | Set number of pods | +| volumeProvisioner.resources | object | `{}` | Set resources | +| volumeProvisioner.serviceAccount | object | `{"annotations":{},"create":true,"name":""}` | Service Account parameters | +| volumeProvisioner.serviceAccount.annotations | object | `{}` | Additional service account annotations | +| volumeProvisioner.serviceAccount.create | bool | `true` | Create service account | +| volumeProvisioner.serviceAccount.name | string | `""` | Override service account name | +| volumeProvisioner.tolerations | list | `[]` | Set tolerations | +| volumeProvisioner.updateStrategy | object | `{"type":"Recreate"}` | Upgrade strategy | + diff --git a/charts/codefresh/cf-runtime/6.4.1/README.md.gotmpl b/charts/codefresh/cf-runtime/6.4.1/README.md.gotmpl new file mode 100644 index 0000000000..96e5ca5748 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/README.md.gotmpl @@ -0,0 +1,1007 @@ +## Codefresh Runner + +{{ template "chart.versionBadge" . }}{{ template "chart.typeBadge" . }}{{ template "chart.appVersionBadge" . }} + +Helm chart for deploying [Codefresh Runner](https://codefresh.io/docs/docs/installation/codefresh-runner/) to Kubernetes. + +## Table of Content + +- [Prerequisites](#prerequisites) +- [Get Chart Info](#get-chart-info) +- [Install Chart](#install-chart) +- [Chart Configuration](#chart-configuration) +- [Upgrade Chart](#upgrade-chart) + - [To 2.x](#to-2-x) + - [To 3.x](#to-3-x) + - [To 4.x](#to-4-x) + - [To 5.x](#to-5-x) + - [To 6.x](#to-6-x) +- [Architecture](#architecture) +- [Configuration](#configuration) + - [EBS backend volume configuration in AWS](#ebs-backend-volume-configuration) + - [Azure Disks backend volume configuration in AKS](#azure-disks-backend-volume-configuration) + - [GCE Disks backend volume configuration in GKE](#gce-disks-backend-volume-configuration-in-gke) + - [Custom volume mounts](#custom-volume-mounts) + - [Custom global environment variables](#custom-global-environment-variables) + - [Volume reuse policy](#volume-reuse-policy) + - [Volume cleaners](#volume-cleaners) + - [Rootless DinD](#rootless-dind) + - [ARM](#arm) + - [Openshift](#openshift) + - [On-premise](#on-premise) + +## Prerequisites + +- Kubernetes **1.19+** +- Helm **3.8.0+** + +⚠️⚠️⚠️ +> Since version 6.2.x chart is pushed **only** to OCI registry at `oci://quay.io/codefresh/cf-runtime` + +> Versions prior to 6.2.x are still available in ChartMuseum at `http://chartmuseum.codefresh.io/cf-runtime` + +## Get Chart Info + +```console +helm show all oci://quay.io/codefresh/cf-runtime +``` +See [Use OCI-based registries](https://helm.sh/docs/topics/registries/) + +## Install Chart + +**Important:** only helm3 is supported + +- Specify the following mandatory values + +`values.yaml` +```yaml +# -- Global parameters +# @default -- See below +global: + # -- User token in plain text (required if `global.codefreshTokenSecretKeyRef` is omitted!) + # Ref: https://g.codefresh.io/user/settings (see API Keys) + # Minimal API key scopes: Runner-Installation(read+write), Agent(read+write), Agents(read+write) + codefreshToken: "" + # -- User token that references an existing secret containing API key (required if `global.codefreshToken` is omitted!) + codefreshTokenSecretKeyRef: {} + # E.g. + # codefreshTokenSecretKeyRef: + # name: my-codefresh-api-token + # key: codefresh-api-token + + # -- Account ID (required!) + # Can be obtained here https://g.codefresh.io/2.0/account-settings/account-information + accountId: "" + + # -- K8s context name (required!) + context: "" + # E.g. + # context: prod-ue1-runtime-1 + + # -- Agent Name (optional!) + # If omitted, the following format will be used '{{ `{{ .Values.global.context }}_{{ .Release.Namespace }}` }}' + agentName: "" + # E.g. + # agentName: prod-ue1-runtime-1 + + # -- Runtime name (optional!) + # If omitted, the following format will be used '{{ `{{ .Values.global.context }}/{{ .Release.Namespace }}` }}' + runtimeName: "" + # E.g. + # runtimeName: prod-ue1-runtime-1/namespace +``` + +- Install chart + +```console +helm upgrade --install cf-runtime oci://quay.io/codefresh/cf-runtime -f values.yaml --create-namespace --namespace codefresh +``` + +## Chart Configuration + +See [Customizing the Chart Before Installing](https://helm.sh/docs/intro/using_helm/#customizing-the-chart-before-installing). + +## Upgrade Chart + +### To 2.x + +This major release renames and deprecated several values in the chart. Most of the workload templates have been refactored. + +Affected values: +- `dockerRegistry` is deprecated. Replaced with `global.imageRegistry` +- `re` is renamed to `runtime` +- `storage.localVolumeMonitor` is replaced with `volumeProvisioner.dind-lv-monitor` +- `volumeProvisioner.volume-cleanup` is replaced with `volumeProvisioner.dind-volume-cleanup` +- `image` values structure has been updated. Split to `image.registry` `image.repository` `image.tag` +- pod's `annotations` is renamed to `podAnnotations` + +### To 3.x + +⚠️⚠️⚠️ +### READ this before the upgrade! + +This major release adds [runtime-environment](https://codefresh.io/docs/docs/installation/codefresh-runner/#runtime-environment-specification) spec into chart templates. +That means it is possible to set parametes for `dind` and `engine` pods via [values.yaml](./values.yaml). + +**If you had any overrides (i.e. tolerations/nodeSelector/environment variables/etc) added in runtime spec via [codefresh CLI](https://codefresh-io.github.io/cli/) (for example, you did use [get](https://codefresh-io.github.io/cli/runtime-environments/get-runtime-environments/) and [patch](https://codefresh-io.github.io/cli/runtime-environments/apply-runtime-environments/) commands to modify the runtime-environment), you MUST add these into chart's [values.yaml](./values.yaml) for `.Values.runtime.dind` or(and) .`Values.runtime.engine`** + +**For backward compatibility, you can disable updating runtime-environment spec via** `.Values.runtime.patch.enabled=false` + +Affected values: +- added **mandatory** `global.codefreshToken`/`global.codefreshTokenSecretKeyRef` **You must specify it before the upgrade!** +- `runtime.engine` is added +- `runtime.dind` is added +- `global.existingAgentToken` is replaced with `global.agentTokenSecretKeyRef` +- `global.existingDindCertsSecret` is replaced with `global.dindCertsSecretRef` + +### To 4.x + +This major release adds **agentless inCluster** runtime mode (relevant only for [Codefresh On-Premises](#on-premise) users) + +Affected values: +- `runtime.agent` / `runtime.inCluster` / `runtime.accounts` / `runtime.description` are added + +### To 5.x + +This major release converts `.runtime.dind.pvcs` from **list** to **dict** + +> 4.x chart's values example: +```yaml +runtime: + dind: + pvcs: + - name: dind + storageClassName: my-storage-class-name + volumeSize: 32Gi + reuseVolumeSelector: 'codefresh-app,io.codefresh.accountName' + reuseVolumeSortOrder: pipeline_id +``` + +> 5.x chart's values example: +```yaml +runtime: + dind: + pvcs: + dind: + name: dind + storageClassName: my-storage-class-name + volumeSize: 32Gi + reuseVolumeSelector: 'codefresh-app,io.codefresh.accountName' + reuseVolumeSortOrder: pipeline_id +``` + +Affected values: +- `.runtime.dind.pvcs` converted from **list** to **dict** + +### To 6.x + +⚠️⚠️⚠️ +### READ this before the upgrade! + +This major release deprecates previously required `codefresh runner init --generate-helm-values-file`. + +Affected values: +- **Replaced** `.monitor.clusterId` with `.global.context` as **mandatory** value! +- **Deprecated** `.global.agentToken` / `.global.agentTokenSecretKeyRef` +- **Removed** `.global.agentId` +- **Removed** `.global.keys` / `.global.dindCertsSecretRef` +- **Removed** `.global.existingAgentToken` / `existingDindCertsSecret` +- **Removed** `.monitor.clusterId` / `.monitor.token` / `.monitor.existingMonitorToken` + +#### Migrate the Helm chart from version 5.x to 6.x + +Given this is the legacy `generated_values.yaml` values: + +> legacy `generated_values.yaml` +```yaml +{ + "appProxy": { + "enabled": false, + }, + "monitor": { + "enabled": false, + "clusterId": "my-cluster-name", + "token": "1234567890" + }, + "global": { + "namespace": "namespace", + "codefreshHost": "https://g.codefresh.io", + "agentToken": "0987654321", + "agentId": "agent-id-here", + "agentName": "my-cluster-name_my-namespace", + "accountId": "my-account-id", + "runtimeName": "my-cluster-name/my-namespace", + "codefreshToken": "1234567890", + "keys": { + "key": "-----BEGIN RSA PRIVATE KEY-----...", + "csr": "-----BEGIN CERTIFICATE REQUEST-----...", + "ca": "-----BEGIN CERTIFICATE-----...", + "serverCert": "-----BEGIN CERTIFICATE-----..." + } + } +} +``` + +Update `values.yaml` for new chart version: + +> For existing installation for backward compatibility `.Values.global.agentToken/agentTokenSecretKeyRef` **must be provided!** For installation from scratch this value is no longer required. + +> updated `values.yaml` +```yaml +global: + codefreshToken: "1234567890" + accountId: "my-account-id" + context: "my-cluster-name" + agentToken: "0987654321" # MANDATORY when migrating from < 6.x chart version ! + agentName: "my-cluster-name_my-namespace" # optional + runtimeName: "my-cluster-name/my-namespace" # optional +``` + +> **Note!** Though it's still possible to update runtime-environment via [get](https://codefresh-io.github.io/cli/runtime-environments/get-runtime-environments/) and [patch](https://codefresh-io.github.io/cli/runtime-environments/apply-runtime-environments/) commands, it's recommended to enable sidecar container to pull runtime spec from Codefresh API to detect any drift in configuration. + +```yaml +runner: + # -- Sidecar container + # Reconciles runtime spec from Codefresh API for drift detection + sidecar: + enabled: true +``` + +## Architecture + +[Codefresh Runner architecture](https://codefresh.io/docs/docs/installation/codefresh-runner/#codefresh-runner-architecture) + +## Configuration + +See [Customizing the Chart Before Installing](https://helm.sh/docs/intro/using_helm/#customizing-the-chart-before-installing). + +### EBS backend volume configuration + +`dind-volume-provisioner` should have permissions to create/attach/detach/delete/get EBS volumes + +Minimal IAM policy for `dind-volume-provisioner` + +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "ec2:AttachVolume", + "ec2:CreateSnapshot", + "ec2:CreateTags", + "ec2:CreateVolume", + "ec2:DeleteSnapshot", + "ec2:DeleteTags", + "ec2:DeleteVolume", + "ec2:DescribeInstances", + "ec2:DescribeSnapshots", + "ec2:DescribeTags", + "ec2:DescribeVolumes", + "ec2:DetachVolume" + ], + "Resource": "*" + } + ] +} +``` + +There are three options: + +1. Run `dind-volume-provisioner` pod on the node/node-group with IAM role + +```yaml +storage: + # -- Set backend volume type (`local`/`ebs`/`ebs-csi`/`gcedisk`/`azuredisk`) + backend: ebs-csi + + ebs: + availabilityZone: "us-east-1a" + +volumeProvisioner: + # -- Set node selector + nodeSelector: {} + # -- Set tolerations + tolerations: [] +``` + +2. Pass static credentials in `.Values.storage.ebs.accessKeyId/accessKeyIdSecretKeyRef` and `.Values.storage.ebs.secretAccessKey/secretAccessKeySecretKeyRef` + +```yaml +storage: + # -- Set backend volume type (`local`/`ebs`/`ebs-csi`/`gcedisk`/`azuredisk`) + backend: ebs-csi + + ebs: + availabilityZone: "us-east-1a" + + # -- Set AWS_ACCESS_KEY_ID for volume-provisioner (optional) + accessKeyId: "" + # -- Existing secret containing AWS_ACCESS_KEY_ID. + accessKeyIdSecretKeyRef: {} + # E.g. + # accessKeyIdSecretKeyRef: + # name: + # key: + + # -- Set AWS_SECRET_ACCESS_KEY for volume-provisioner (optional) + secretAccessKey: "" + # -- Existing secret containing AWS_SECRET_ACCESS_KEY + secretAccessKeySecretKeyRef: {} + # E.g. + # secretAccessKeySecretKeyRef: + # name: + # key: +``` + +3. Assign IAM role to `dind-volume-provisioner` service account + +```yaml +storage: + # -- Set backend volume type (`local`/`ebs`/`ebs-csi`/`gcedisk`/`azuredisk`) + backend: ebs-csi + + ebs: + availabilityZone: "us-east-1a" + +volumeProvisioner: + # -- Service Account parameters + serviceAccount: + # -- Create service account + create: true + # -- Additional service account annotations + annotations: + eks.amazonaws.com/role-arn: "arn:aws:iam:::role/" +``` + +### Custom volume mounts + +You can add your own volumes and volume mounts in the runtime environment, so that all pipeline steps will have access to the same set of external files. + +```yaml +runtime: + dind: + userVolumes: + regctl-docker-registry: + name: regctl-docker-registry + secret: + items: + - key: .dockerconfigjson + path: config.json + secretName: regctl-docker-registry + optional: true + userVolumeMounts: + regctl-docker-registry: + name: regctl-docker-registry + mountPath: /home/appuser/.docker/ + readOnly: true + +``` + +### Azure Disks backend volume configuration + +`dind-volume-provisioner` should have permissions to create/delete/get Azure Disks + +Role definition for `dind-volume-provisioner` + +`dind-volume-provisioner-role.json` +```json +{ + "Name": "CodefreshDindVolumeProvisioner", + "Description": "Perform create/delete/get disks", + "IsCustom": true, + "Actions": [ + "Microsoft.Compute/disks/read", + "Microsoft.Compute/disks/write", + "Microsoft.Compute/disks/delete" + + ], + "AssignableScopes": ["/subscriptions/"] +} +``` + +When creating an AKS cluster in Azure there is the option to use a [managed identity](https://learn.microsoft.com/en-us/azure/aks/use-managed-identity) that is assigned to the kubelet. This identity is assigned to the underlying node pool in the AKS cluster and can then be used by the dind-volume-provisioner. + +```console +export ROLE_DEFINITIN_FILE=dind-volume-provisioner-role.json +export SUBSCRIPTION_ID=$(az account show --query "id" | xargs echo ) +export RESOURCE_GROUP= +export AKS_NAME= +export LOCATION=$(az aks show -g $RESOURCE_GROUP -n $AKS_NAME --query location | xargs echo) +export NODES_RESOURCE_GROUP=MC_${RESOURCE_GROUP}_${AKS_NAME}_${LOCATION} +export NODE_SERVICE_PRINCIPAL=$(az aks show -g $RESOURCE_GROUP -n $AKS_NAME --query identityProfile.kubeletidentity.objectId | xargs echo) + +az role definition create --role-definition @${ROLE_DEFINITIN_FILE} +az role assignment create --assignee $NODE_SERVICE_PRINCIPAL --scope /subscriptions/$SUBSCRIPTION_ID/resourceGroups/$NODES_RESOURCE_GROUP --role CodefreshDindVolumeProvisioner +``` + +Deploy Helm chart with the following values: + +`values.yaml` +```yaml +volumeProvisioner: + podSecurityContext: + enabled: true + runAsUser: 0 + runAsGroup: 0 + fsGroup: 0 + +storage: + backend: azuredisk + azuredisk: + availabilityZone: northeurope-1 # replace with your zone + resourceGroup: my-resource-group-name + + mountAzureJson: true + +runtime: + dind: + nodeSelector: + topology.kubernetes.io/zone: northeurope-1 +``` + +### GCE Disks backend volume configuration in GKE + +`dind-volume-provisioner` should have `ComputeEngine.StorageAdmin` permissions + +There are three options: + +1. Run `dind-volume-provisioner` pod on the node/node-group with IAM Service Account + +```yaml +storage: + # -- Set backend volume type (`local`/`ebs`/`ebs-csi`/`gcedisk`/`azuredisk`) + backend: gcedisk + + gcedisk: + # -- Set GCP volume backend type (`pd-ssd`/`pd-standard`) + volumeType: "pd-standard" + # -- Set GCP volume availability zone + availabilityZone: "us-central1-c" + +volumeProvisioner: + # -- Set node selector + nodeSelector: {} + # -- Set tolerations + tolerations: [] + +# -- Set runtime parameters +runtime: + # -- Parameters for DinD (docker-in-docker) pod + dind: + # -- Set node selector. + nodeSelector: + topology.kubernetes.io/zone: us-central1-c +``` + +2. Pass static credentials in `.Values.storage.gcedisk.serviceAccountJson` (inline) or `.Values.storage.gcedisk.serviceAccountJsonSecretKeyRef` (from your own secret) + +```yaml +storage: + # -- Set backend volume type (`local`/`ebs`/`ebs-csi`/`gcedisk`/`azuredisk`) + backend: gcedisk + + gcedisk: + # -- Set GCP volume backend type (`pd-ssd`/`pd-standard`) + volumeType: "`pd-standard" + # -- Set GCP volume availability zone + availabilityZone: "us-central1-c" + # -- Set Google SA JSON key for volume-provisioner (optional) + serviceAccountJson: | + { + "type": "service_account", + "project_id": "...", + "private_key_id": "...", + "private_key": "...", + "client_email": "...", + "client_id": "...", + "auth_uri": "...", + "token_uri": "...", + "auth_provider_x509_cert_url": "...", + "client_x509_cert_url": "..." + } + # -- Existing secret containing containing Google SA JSON key for volume-provisioner (optional) + serviceAccountJsonSecretKeyRef: {} + # E.g.: + # serviceAccountJsonSecretKeyRef: + # name: gce-service-account + # key: service-account.json + +# -- Set runtime parameters +runtime: + # -- Parameters for DinD (docker-in-docker) pod + dind: + # -- Set node selector. + nodeSelector: + topology.kubernetes.io/zone: us-central1-c +``` + +3. Assign IAM role to `dind-volume-provisioner` service account + +```yaml +storage: + # -- Set backend volume type (`local`/`ebs`/`ebs-csi`/`gcedisk`/`azuredisk`) + backend: gcedisk + + gcedisk: + # -- Set GCP volume backend type (`pd-ssd`/`pd-standard`) + volumeType: "`pd-standard" + # -- Set GCP volume availability zone + availabilityZone: "us-central1-c" + +volumeProvisioner: + # -- Service Account parameters + serviceAccount: + # -- Create service account + create: true + # -- Additional service account annotations + annotations: + iam.gke.io/gcp-service-account: @.iam.gserviceaccount.com + +# -- Set runtime parameters +runtime: + # -- Parameters for DinD (docker-in-docker) pod + dind: + # -- Set node selector. + nodeSelector: + topology.kubernetes.io/zone: us-central1-c +``` + +### Custom global environment variables + +You can add your own environment variables to the runtime environment. All pipeline steps have access to the global variables. + +```yaml +runtime: + engine: + userEnvVars: + - name: GITHUB_TOKEN + valueFrom: + secretKeyRef: + name: github-token + key: token +``` + +### Volume reuse policy + +Volume reuse behavior depends on the configuration for `reuseVolumeSelector` in the runtime environment spec. + +```yaml +runtime: + dind: + pvcs: + - name: dind + ... + reuseVolumeSelector: 'codefresh-app,io.codefresh.accountName' + reuseVolumeSortOrder: pipeline_id +``` + +The following options are available: +- `reuseVolumeSelector: 'codefresh-app,io.codefresh.accountName'` - PV can be used by ANY pipeline in the specified account (default). +Benefit: Fewer PVs, resulting in lower costs. Since any PV can be used by any pipeline, the cluster needs to maintain/reserve fewer PVs in its PV pool for Codefresh. +Downside: Since the PV can be used by any pipeline, the PVs could have assets and info from different pipelines, reducing the probability of cache. + +- `reuseVolumeSelector: 'codefresh-app,io.codefresh.accountName,project_id'` - PV can be used by ALL pipelines in your account, assigned to the same project. + +- `reuseVolumeSelector: 'codefresh-app,io.codefresh.accountName,pipeline_id'` - PV can be used only by a single pipeline. +Benefit: More probability of cache without “spam” from other pipelines. +Downside: More PVs to maintain and therefore higher costs. + +- `reuseVolumeSelector: 'codefresh-app,io.codefresh.accountName,pipeline_id,io.codefresh.branch_name'` - PV can be used only by single pipeline AND single branch. + +- `reuseVolumeSelector: 'codefresh-app,io.codefresh.accountName,pipeline_id,trigger'` - PV can be used only by single pipeline AND single trigger. + +### Volume cleaners + +Codefresh pipelines require disk space for: + * [Pipeline Shared Volume](https://codefresh.io/docs/docs/pipelines/introduction-to-codefresh-pipelines/#sharing-the-workspace-between-build-steps) (`/codefresh/volume`, implemented as [docker volume](https://docs.docker.com/storage/volumes/)) + * Docker containers, both running and stopped + * Docker images and cached layers + +Codefresh offers two options to manage disk space and prevent out-of-space errors: +* Use runtime cleaners on Docker images and volumes +* [Set the minimum disk space per pipeline build volume](https://codefresh.io/docs/docs/pipelines/pipelines/#set-minimum-disk-space-for-a-pipeline-build) + +To improve performance by using Docker cache, Codefresh `volume-provisioner` can provision previously used disks with Docker images and pipeline volumes from previously run builds. + +### Types of runtime volume cleaners + +Docker images and volumes must be cleaned on a regular basis. + +* [IN-DIND cleaner](https://github.com/codefresh-io/dind/tree/master/cleaner): Deletes extra Docker containers, volumes, and images in **DIND pod**. +* [External volume cleaner](https://github.com/codefresh-io/dind-volume-cleanup): Deletes unused **external** PVs (EBS, GCE/Azure disks). +* [Local volume cleaner](https://github.com/codefresh-io/dind-volume-utils/blob/master/local-volumes/lv-cleaner.sh): Deletes **local** volumes if node disk space is close to the threshold. + +### IN-DIND cleaner + +**Purpose:** Removes unneeded *docker containers, images, volumes* inside Kubernetes volume mounted on the DIND pod + +**How it runs:** Inside each DIND pod as script + +**Triggered by:** SIGTERM and also during the run when disk usage > 90% (configurable) + +**Configured by:** Environment Variables which can be set in Runtime Environment spec + +**Configuration/Logic:** [README.md](https://github.com/codefresh-io/dind/tree/master/cleaner#readme) + +Override `.Values.runtime.dind.env` if necessary (the following are **defaults**): + +```yaml +runtime: + dind: + env: + CLEAN_PERIOD_SECONDS: '21600' # launch clean if last clean was more than CLEAN_PERIOD_SECONDS seconds ago + CLEAN_PERIOD_BUILDS: '5' # launch clean if last clean was more CLEAN_PERIOD_BUILDS builds since last build + IMAGE_RETAIN_PERIOD: '14400' # do not delete docker images if they have events since current_timestamp - IMAGE_RETAIN_PERIOD + VOLUMES_RETAIN_PERIOD: '14400' # do not delete docker volumes if they have events since current_timestamp - VOLUMES_RETAIN_PERIOD + DISK_USAGE_THRESHOLD: '0.8' # launch clean based on current disk usage DISK_USAGE_THRESHOLD + INODES_USAGE_THRESHOLD: '0.8' # launch clean based on current inodes usage INODES_USAGE_THRESHOLD +``` + +### External volumes cleaner + +**Purpose:** Removes unused *kubernetes volumes and related backend volumes* + +**How it runs:** Runs as `dind-volume-cleanup` CronJob. Installed in case the Runner uses non-local volumes `.Values.storage.backend != local` + +**Triggered by:** CronJob every 10min (configurable) + +**Configuration:** + +Set `codefresh.io/volume-retention` for dinds' PVCs: + +```yaml +runtime: + dind: + pvcs: + dind: + ... + annotations: + codefresh.io/volume-retention: 7d +``` + +Or override environment variables for `dind-volume-cleanup` cronjob: + +```yaml +volumeProvisioner: + dind-volume-cleanup: + env: + RETENTION_DAYS: 7 # clean volumes that were last used more than `RETENTION_DAYS` (default is 4) ago +``` + +### Local volumes cleaner + +**Purpose:** Deletes local volumes when node disk space is close to the threshold + +**How it runs:** Runs as `dind-lv-monitor` DaemonSet. Installed in case the Runner uses local volumes `.Values.storage.backend == local` + +**Triggered by:** Disk space usage or inode usage that exceeds thresholds (configurable) + +**Configuration:** + +Override environment variables for `dind-lv-monitor` daemonset: + +```yaml +volumeProvisioner: + dind-lv-monitor: + env: + KB_USAGE_THRESHOLD: 60 # default 80 (percentage) + INODE_USAGE_THRESHOLD: 60 # default 80 +``` + +### Rootless DinD + +DinD pod runs a `priviliged` container with **rootfull** docker. +To run the docker daemon as non-root user (**rootless** mode), change dind image tag: + +`values.yaml` +```yaml +runtime: + dind: + image: + tag: rootless +``` + +### ARM + +With the Codefresh Runner, you can run native ARM64v8 builds. + +> **Note!** +> You cannot run both amd64 and arm64 images within the same pipeline. As one pipeline can map only to one runtime, you can run either amd64 or arm64 within the same pipeline. + +Provide `nodeSelector` and(or) `tolerations` for dind pods: + +`values.yaml` +```yaml +runtime: + dind: + nodeSelector: + arch: arm64 + tolerations: + - key: arch + operator: Equal + value: arm64 + effect: NoSchedule +``` + +### Openshift + +To install Codefresh Runner on OpenShift use the following `values.yaml` example + +```yaml +runner: + podSecurityContext: + enabled: false + +volumeProvisioner: + podSecurityContext: + enabled: false + env: + PRIVILEGED_CONTAINER: true + dind-lv-monitor: + containerSecurityContext: + enabled: true + privileged: true + volumePermissions: + enabled: true + securityContext: + privileged: true + runAsUser: auto +``` + +Grant `privileged` SCC to `cf-runtime-runner` and `cf-runtime-volume-provisioner` service accounts. + +```console +oc adm policy add-scc-to-user privileged system:serviceaccount:codefresh:cf-runtime-runner + +oc adm policy add-scc-to-user privileged system:serviceaccount:codefresh:cf-runtime-volume-provisioner +``` + +### On-premise + +If you have [Codefresh On-Premises](https://artifacthub.io/packages/helm/codefresh-onprem/codefresh) deployed, you can install Codefresh Runner in **agentless** mode. + +**What is agentless mode?** + +Agent (aka venona) is Runner component which responsible for calling Codefresh API to run builds and create dind/engine pods and pvc objects. Agent can only be assigned to a single account, thus you can't share one runtime across multiple accounts. However, with **agentless** mode it's possible to register the runtime as **system**-type runtime so it's registered on the platform level and can be assigned/shared across multiple accounts. + +**What are the prerequisites?** +- You have a running [Codefresh On-Premises](https://artifacthub.io/packages/helm/codefresh-onprem/codefresh) control-plane environment +- You have a Codefresh API token with platform **Admin** permissions scope + + +### How to deploy agentless runtime when it's on the SAME k8s cluster as On-Premises control-plane environment? + +- Enable cluster-level permissions for cf-api (On-Premises control-plane component) + +> `values.yaml` for [Codefresh On-Premises](https://artifacthub.io/packages/helm/codefresh-onprem/codefresh) Helm chart +```yaml +cfapi: + ... + # -- Enable ClusterRole/ClusterRoleBinding + rbac: + namespaced: false +``` + +- Set the following values for Runner Helm chart + +`.Values.global.codefreshHost=...` \ +`.Values.global.codefreshToken=...` \ +`.Values.global.runtimeName=system/...` \ +`.Values.runtime.agent=false` \ +`.Values.runtime.inCluster=true` + +> `values.yaml` for [Codefresh Runner](https://artifacthub.io/packages/helm/codefresh-runner/cf-runtime) helm chart +```yaml +global: + # -- URL of Codefresh On-Premises Platform + codefreshHost: "https://myonprem.somedomain.com" + # -- User token in plain text with Admin permission scope + codefreshToken: "" + # -- User token that references an existing secret containing API key. + codefreshTokenSecretKeyRef: {} + # E.g. + # codefreshTokenSecretKeyRef: + # name: my-codefresh-api-token + # key: codefresh-api-token + + # -- Distinguished runtime name + # (for On-Premise only; mandatory!) Must be prefixed with "system/..." + runtimeName: "system/prod-ue1-some-cluster-name" + +# -- Set runtime parameters +runtime: + # -- (for On-Premise only; mandatory!) Disable agent + agent: false + # -- (for On-Premise only; optional) Set inCluster runtime (default: `true`) + # `inCluster=true` flag is set when Runtime and On-Premises control-plane are run on the same cluster + # `inCluster=false` flag is set when Runtime and On-Premises control-plane are on different clusters + inCluster: true + # -- (for On-Premise only; optional) Assign accounts to runtime (list of account ids; default is empty) + # Accounts can be assigned to the runtime in Codefresh UI later so you can kepp it empty. + accounts: [] + # -- Set parent runtime to inherit. + runtimeExtends: [] +``` + +- Install the chart + +```console +helm upgrade --install cf-runtime oci://quay.io/codefresh/cf-runtime -f values.yaml --create-namespace --namespace cf-runtime +``` + +- Verify the runtime and run test pipeline + +Go to [https:///admin/runtime-environments/system](https:///admin/runtime-environments/system) to check the runtime. Assign it to the required account(s). Run test pipeline on it. + + +### How to deploy agentless runtime when it's on the DIFFERENT k8s cluster than On-Premises control-plane environment? + +In this case, it's required to mount runtime cluster's `KUBECONFIG` into On-Premises `cf-api` deployment + +- Create the neccessary RBAC resources + +> `values.yaml` for [Codefresh Runner](https://artifacthub.io/packages/helm/codefresh-runner/cf-runtime) helm chart +```yaml +extraResources: +- apiVersion: rbac.authorization.k8s.io/v1 + kind: Role + metadata: + name: codefresh-role + namespace: '{{ "{{ .Release.Namespace }}" }}' + rules: + - apiGroups: [""] + resources: ["pods", "persistentvolumeclaims", "persistentvolumes"] + verbs: ["list", "watch", "get", "create", "patch", "delete"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots"] + verbs: ["list", "watch", "get", "create", "patch", "delete"] +- apiVersion: v1 + kind: ServiceAccount + metadata: + name: codefresh-runtime-user + namespace: '{{ "{{ .Release.Namespace }}" }}' +- apiVersion: rbac.authorization.k8s.io/v1 + kind: RoleBinding + metadata: + name: codefresh-runtime-user + namespace: '{{ "{{ .Release.Namespace }}" }}' + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: codefresh-role + subjects: + - kind: ServiceAccount + name: codefresh-runtime-user + namespace: '{{ "{{ .Release.Namespace }}" }}' +- apiVersion: v1 + kind: Secret + metadata: + name: codefresh-runtime-user-token + namespace: '{{ "{{ .Release.Namespace }}" }}' + annotations: + kubernetes.io/service-account.name: codefresh-runtime-user + type: kubernetes.io/service-account-token +``` + +- Set up the following environment variables to create a `KUBECONFIG` file + +```shell +NAMESPACE=cf-runtime +CLUSTER_NAME=prod-ue1-some-cluster-name +CURRENT_CONTEXT=$(kubectl config current-context) + +USER_TOKEN_VALUE=$(kubectl -n cf-runtime get secret/codefresh-runtime-user-token -o=go-template='{{ `{{.data.token}}` }}' | base64 --decode) +CURRENT_CLUSTER=$(kubectl config view --raw -o=go-template='{{ `{{range .contexts}}{{if eq .name "'''${CURRENT_CONTEXT}'''"}}{{ index .context "cluster" }}{{end}}{{end}}` }}') +CLUSTER_CA=$(kubectl config view --raw -o=go-template='{{ `{{range .clusters}}{{if eq .name "'''${CURRENT_CLUSTER}'''"}}"{{with index .cluster "certificate-authority-data" }}{{.}}{{end}}"{{ end }}{{ end }}` }}') +CLUSTER_SERVER=$(kubectl config view --raw -o=go-template='{{ `{{range .clusters}}{{if eq .name "'''${CURRENT_CLUSTER}'''"}}{{ .cluster.server }}{{end}}{{ end }}` }}') + +export -p USER_TOKEN_VALUE CURRENT_CONTEXT CURRENT_CLUSTER CLUSTER_CA CLUSTER_SERVER CLUSTER_NAME +``` + +- Create a kubeconfig file + +```console +cat << EOF > $CLUSTER_NAME-kubeconfig +apiVersion: v1 +kind: Config +current-context: ${CLUSTER_NAME} +contexts: +- name: ${CLUSTER_NAME} + context: + cluster: ${CLUSTER_NAME} + user: codefresh-runtime-user + namespace: ${NAMESPACE} +clusters: +- name: ${CLUSTER_NAME} + cluster: + certificate-authority-data: ${CLUSTER_CA} + server: ${CLUSTER_SERVER} +users: +- name: ${CLUSTER_NAME} + user: + token: ${USER_TOKEN_VALUE} +EOF +``` + +- **Switch context to On-Premises control-plane cluster**. Create k8s secret (via any tool like [ESO](https://external-secrets.io/v0.4.4/), `kubectl`, etc ) containing runtime cluster's `KUBECONFG` created in previous step. + +```shell +NAMESPACE=codefresh +kubectl create secret generic dind-runtime-clusters --from-file=$CLUSTER_NAME=$CLUSTER_NAME-kubeconfig -n $NAMESPACE +``` + +- Mount secret containing runtime cluster's `KUBECONFG` into cf-api in On-Premises control-plane cluster + +> `values.yaml` for [Codefresh On-Premises](https://artifacthub.io/packages/helm/codefresh-onprem/codefresh) helm chart +```yaml +cf-api: + ... + volumes: + dind-clusters: + enabled: true + type: secret + nameOverride: dind-runtime-clusters + optional: true +``` +> volumeMount `/etc/kubeconfig` is already configured in cf-api Helm chart template. No need to specify it. + +- Set the following values for Runner helm chart + +> `values.yaml` for [Codefresh Runner](https://artifacthub.io/packages/helm/codefresh-runner/cf-runtime) helm chart + +`.Values.global.codefreshHost=...` \ +`.Values.global.codefreshToken=...` \ +`.Values.global.runtimeName=system/...` \ +`.Values.runtime.agent=false` \ +`.Values.runtime.inCluster=false` + +**Important!** +`.Values.global.name` ("system/" prefix is ignored!) should match the cluster name (key in `dind-runtime-clusters` secret created previously) +```yaml +global: + # -- URL of Codefresh On-Premises Platform + codefreshHost: "https://myonprem.somedomain.com" + # -- User token in plain text with Admin permission scope + codefreshToken: "" + # -- User token that references an existing secret containing API key. + codefreshTokenSecretKeyRef: {} + # E.g. + # codefreshTokenSecretKeyRef: + # name: my-codefresh-api-token + # key: codefresh-api-token + + # -- Distinguished runtime name + # (for On-Premise only; mandatory!) Must be prefixed with "system/..." + name: "system/prod-ue1-some-cluster-name" + +# -- Set runtime parameters +runtime: + # -- (for On-Premise only; mandatory!) Disable agent + agent: false + # -- (for On-Premise only; optional) Set inCluster runtime (default: `true`) + # `inCluster=true` flag is set when Runtime and On-Premises control-plane are run on the same cluster + # `inCluster=false` flag is set when Runtime and On-Premises control-plane are on different clusters + inCluster: false + # -- (for On-Premise only; optional) Assign accounts to runtime (list of account ids; default is empty) + # Accounts can be assigned to the runtime in Codefresh UI later so you can kepp it empty. + accounts: [] + # -- (optional) Set parent runtime to inherit. + runtimeExtends: [] +``` + +- Install the chart + +```console +helm upgrade --install cf-runtime oci://quay.io/codefresh/cf-runtime -f values.yaml --create-namespace --namespace cf-runtime +``` + +- Verify the runtime and run test pipeline + +Go to [https:///admin/runtime-environments/system](https:///admin/runtime-environments/system) to see the runtime. Assign it to the required account(s). + +{{ template "chart.requirementsSection" . }} + +{{ template "chart.valuesSection" . }} + diff --git a/charts/codefresh/cf-runtime/6.4.1/files/cleanup-runtime.sh b/charts/codefresh/cf-runtime/6.4.1/files/cleanup-runtime.sh new file mode 100644 index 0000000000..c1fc5f3682 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/files/cleanup-runtime.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +echo "-----" +echo "API_HOST: ${API_HOST}" +echo "AGENT_NAME: ${AGENT_NAME}" +echo "RUNTIME_NAME: ${RUNTIME_NAME}" +echo "AGENT: ${AGENT}" +echo "AGENT_SECRET_NAME: ${AGENT_SECRET_NAME}" +echo "DIND_SECRET_NAME: ${DIND_SECRET_NAME}" +echo "-----" + +auth() { + codefresh auth create-context --api-key ${API_TOKEN} --url ${API_HOST} +} + +remove_runtime() { + if [ "$AGENT" == "true" ]; then + codefresh delete re ${RUNTIME_NAME} || true + else + codefresh delete sys-re ${RUNTIME_NAME} || true + fi +} + +remove_agent() { + codefresh delete agent ${AGENT_NAME} || true +} + +remove_secrets() { + kubectl patch secret $(kubectl get secret -l codefresh.io/internal=true | awk 'NR>1{print $1}' | xargs) -p '{"metadata":{"finalizers":null}}' --type=merge || true + kubectl delete secret $AGENT_SECRET_NAME || true + kubectl delete secret $DIND_SECRET_NAME || true +} + +auth +remove_runtime +remove_agent +remove_secrets \ No newline at end of file diff --git a/charts/codefresh/cf-runtime/6.4.1/files/configure-dind-certs.sh b/charts/codefresh/cf-runtime/6.4.1/files/configure-dind-certs.sh new file mode 100644 index 0000000000..a1092eb1e6 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/files/configure-dind-certs.sh @@ -0,0 +1,132 @@ +#!/usr/bin/env bash +# + +#--- +fatal() { + echo "ERROR: $1" + exit 1 +} + +msg() { echo -e "\e[32mINFO ---> $1\e[0m"; } +err() { echo -e "\e[31mERR ---> $1\e[0m" ; return 1; } + +exit_trap () { + local lc="$BASH_COMMAND" rc=$? + if [ $rc != 0 ]; then + if [[ -n "$SLEEP_ON_ERROR" ]]; then + echo -e "\nSLEEP_ON_ERROR is set - Sleeping to fix error" + sleep $SLEEP_ON_ERROR + fi + fi +} +trap exit_trap EXIT + +usage() { + echo "Usage: + $0 [-n | --namespace] [--server-cert-cn] [--server-cert-extra-sans] codefresh-api-host codefresh-api-token + +Example: + $0 -n workflow https://g.codefresh.io 21341234.423141234.412431234 + +" +} + +# Args +while [[ $1 =~ ^(-(n|h)|--(namespace|server-cert-cn|server-cert-extra-sans|help)) ]] +do + key=$1 + value=$2 + + case $key in + -h|--help) + usage + exit + ;; + -n|--namespace) + NAMESPACE="$value" + shift + ;; + --server-cert-cn) + SERVER_CERT_CN="$value" + shift + ;; + --server-cert-extra-sans) + SERVER_CERT_EXTRA_SANS="$value" + shift + ;; + esac + shift # past argument or value +done + +API_HOST=${1:-"$CF_API_HOST"} +API_TOKEN=${2:-"$CF_API_TOKEN"} + +[[ -z "$API_HOST" ]] && usage && fatal "Missing API_HOST" +[[ -z "$API_TOKEN" ]] && usage && fatal "Missing token" + + +API_SIGN_PATH=${API_SIGN_PATH:-"api/custom_clusters/signServerCerts"} + +NAMESPACE=${NAMESPACE:-default} +RELEASE=${RELEASE:-cf-runtime} + +DIR=$(dirname $0) +TMPDIR=/tmp/codefresh/ + +TMP_CERTS_FILE_ZIP=$TMPDIR/cf-certs.zip +TMP_CERTS_HEADERS_FILE=$TMPDIR/cf-certs-response-headers.txt +CERTS_DIR=$TMPDIR/ssl +SRV_TLS_CA_CERT=${CERTS_DIR}/ca.pem +SRV_TLS_KEY=${CERTS_DIR}/server-key.pem +SRV_TLS_CSR=${CERTS_DIR}/server-cert.csr +SRV_TLS_CERT=${CERTS_DIR}/server-cert.pem +CF_SRV_TLS_CERT=${CERTS_DIR}/cf-server-cert.pem +CF_SRV_TLS_CA_CERT=${CERTS_DIR}/cf-ca.pem +mkdir -p $TMPDIR $CERTS_DIR + +K8S_CERT_SECRET_NAME=codefresh-certs-server +echo -e "\n------------------\nGenerating server tls certificates ... " + +SERVER_CERT_CN=${SERVER_CERT_CN:-"docker.codefresh.io"} +SERVER_CERT_EXTRA_SANS="${SERVER_CERT_EXTRA_SANS}" +### + + openssl genrsa -out $SRV_TLS_KEY 4096 || fatal "Failed to generate openssl key " + openssl req -subj "/CN=${SERVER_CERT_CN}" -new -key $SRV_TLS_KEY -out $SRV_TLS_CSR || fatal "Failed to generate openssl csr " + GENERATE_CERTS=true + CSR=$(sed ':a;N;$!ba;s/\n/\\n/g' ${SRV_TLS_CSR}) + + SERVER_CERT_SANS="IP:127.0.0.1,DNS:dind,DNS:*.dind.${NAMESPACE},DNS:*.dind.${NAMESPACE}.svc${KUBE_DOMAIN},DNS:*.cf-cd.com,DNS:*.codefresh.io" + if [[ -n "${SERVER_CERT_EXTRA_SANS}" ]]; then + SERVER_CERT_SANS=${SERVER_CERT_SANS},${SERVER_CERT_EXTRA_SANS} + fi + echo "{\"reqSubjectAltName\": \"${SERVER_CERT_SANS}\", \"csr\": \"${CSR}\" }" > ${TMPDIR}/sign_req.json + + rm -fv ${TMP_CERTS_HEADERS_FILE} ${TMP_CERTS_FILE_ZIP} + + SIGN_STATUS=$(curl -k -sSL -d @${TMPDIR}/sign_req.json -H "Content-Type: application/json" -H "Authorization: ${API_TOKEN}" -H "Expect: " \ + -o ${TMP_CERTS_FILE_ZIP} -D ${TMP_CERTS_HEADERS_FILE} -w '%{http_code}' ${API_HOST}/${API_SIGN_PATH} ) + + echo "Sign request completed with HTTP_STATUS_CODE=$SIGN_STATUS" + if [[ $SIGN_STATUS != 200 ]]; then + echo "ERROR: Cannot sign certificates" + if [[ -f ${TMP_CERTS_FILE_ZIP} ]]; then + mv ${TMP_CERTS_FILE_ZIP} ${TMP_CERTS_FILE_ZIP}.error + cat ${TMP_CERTS_FILE_ZIP}.error + fi + exit 1 + fi + unzip -o -d ${CERTS_DIR}/ ${TMP_CERTS_FILE_ZIP} || fatal "Failed to unzip certificates to ${CERTS_DIR} " + cp -v ${CF_SRV_TLS_CA_CERT} $SRV_TLS_CA_CERT || fatal "received ${TMP_CERTS_FILE_ZIP} does not contains ca.pem" + cp -v ${CF_SRV_TLS_CERT} $SRV_TLS_CERT || fatal "received ${TMP_CERTS_FILE_ZIP} does not contains cf-server-cert.pem" + + +echo -e "\n------------------\nCreating certificate secret " + +kubectl -n $NAMESPACE create secret generic $K8S_CERT_SECRET_NAME \ + --from-file=$SRV_TLS_CA_CERT \ + --from-file=$SRV_TLS_KEY \ + --from-file=$SRV_TLS_CERT \ + --dry-run=client -o yaml | kubectl apply --overwrite -f - +kubectl -n $NAMESPACE label --overwrite secret ${K8S_CERT_SECRET_NAME} codefresh.io/internal=true +kubectl -n $NAMESPACE patch secret $K8S_CERT_SECRET_NAME -p '{"metadata": {"finalizers": ["kubernetes"]}}' diff --git a/charts/codefresh/cf-runtime/6.4.1/files/init-runtime.sh b/charts/codefresh/cf-runtime/6.4.1/files/init-runtime.sh new file mode 100644 index 0000000000..eb3488af11 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/files/init-runtime.sh @@ -0,0 +1,80 @@ +#!/bin/bash + +echo "-----" +echo "API_HOST: ${API_HOST}" +echo "AGENT_NAME: ${AGENT_NAME}" +echo "KUBE_CONTEXT: ${KUBE_CONTEXT}" +echo "KUBE_NAMESPACE: ${KUBE_NAMESPACE}" +echo "OWNER_NAME: ${OWNER_NAME}" +echo "RUNTIME_NAME: ${RUNTIME_NAME}" +echo "SECRET_NAME: ${SECRET_NAME}" +echo "-----" + +create_agent_secret() { + + kubectl apply -f - < $1\e[0m"; } +err() { echo -e "\e[31mERR ---> $1\e[0m" ; return 1; } + + +if [ -z "${USER_CODEFRESH_TOKEN}" ]; then + err "missing codefresh user token. must supply \".global.codefreshToken\" if agent-codefresh-token does not exist" + exit 1 +fi + +codefresh auth create-context --api-key ${USER_CODEFRESH_TOKEN} --url ${API_HOST} + +while true; do + msg "Reconciling ${RUNTIME_NAME} runtime" + + sleep $RECONCILE_INTERVAL + + codefresh get re \ + --name ${RUNTIME_NAME} \ + -o yaml \ + | yq 'del(.version, .metadata.changedBy, .metadata.creationTime)' > /tmp/runtime.yaml + + kubectl get cm ${CONFIGMAP_NAME} -n ${KUBE_NAMESPACE} -o yaml \ + | yq 'del(.metadata.resourceVersion, .metadata.uid)' \ + | yq eval '.data["runtime.yaml"] = load_str("/tmp/runtime.yaml")' \ + | kubectl apply -f - +done diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/_components/app-proxy/_deployment.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/_components/app-proxy/_deployment.yaml new file mode 100644 index 0000000000..26f3576b77 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/_components/app-proxy/_deployment.yaml @@ -0,0 +1,70 @@ +{{- define "app-proxy.resources.deployment" -}} +{{ $cfCommonTplSemver := printf "cf-common-%s" (index .Subcharts "cf-common").Chart.Version }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "app-proxy.fullname" . }} + labels: + {{- include "app-proxy.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.replicasCount }} + strategy: + type: {{ .Values.updateStrategy.type }} + selector: + matchLabels: + {{- include "app-proxy.selectorLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "app-proxy.selectorLabels" . | nindent 8 }} + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- include (printf "%s.image.pullSecrets" $cfCommonTplSemver ) . | nindent 8 }} + serviceAccountName: {{ include "app-proxy.serviceAccountName" . }} + {{- if .Values.podSecurityContext.enabled }} + securityContext: {{- omit .Values.podSecurityContext "enabled" | toYaml | nindent 8 }} + {{- end }} + containers: + - name: app-proxy + image: {{ include (printf "%s.image.name" $cfCommonTplSemver ) (dict "image" .Values.image "context" .) }} + imagePullPolicy: {{ .Values.image.pullPolicy | default "Always" }} + env: + {{- include "app-proxy.environment-variables" . | nindent 8 }} + ports: + - name: http + containerPort: 3000 + readinessProbe: + initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.readinessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }} + successThreshold: {{ .Values.readinessProbe.successThreshold }} + failureThreshold: {{ .Values.readinessProbe.failureThreshold }} + httpGet: + path: /health + port: http + resources: + {{- toYaml .Values.resources | nindent 12 }} + volumeMounts: + {{- with .Values.extraVolumeMounts }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 6 }} + {{- end }} + volumes: + {{- with .Values.extraVolumes }} + {{- toYaml . | nindent 6 }} + {{- end }} +{{- end -}} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/_components/app-proxy/_env-vars.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/_components/app-proxy/_env-vars.yaml new file mode 100644 index 0000000000..c9b9a0e36a --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/_components/app-proxy/_env-vars.yaml @@ -0,0 +1,19 @@ +{{- define "app-proxy.environment-variables.defaults" }} +PORT: 3000 +{{- end }} + +{{- define "app-proxy.environment-variables.calculated" }} +CODEFRESH_HOST: {{ include "runtime.runtime-environment-spec.codefresh-host" . }} +{{- with .Values.ingress.pathPrefix }} +API_PATH_PREFIX: {{ . | quote }} +{{- end }} +{{- end }} + +{{- define "app-proxy.environment-variables" }} +{{- $cfCommonTplSemver := printf "cf-common-%s" (index .Subcharts "cf-common").Chart.Version }} +{{- $defaults := (include "app-proxy.environment-variables.defaults" . | fromYaml) }} +{{- $calculated := (include "app-proxy.environment-variables.calculated" . | fromYaml) }} +{{- $overrides := .Values.env }} +{{- $mergedValues := mergeOverwrite (merge $defaults $calculated) $overrides }} +{{- include (printf "%s.env-vars" $cfCommonTplSemver) (dict "Values" $mergedValues "context" .) }} +{{- end }} \ No newline at end of file diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/_components/app-proxy/_helpers.tpl b/charts/codefresh/cf-runtime/6.4.1/templates/_components/app-proxy/_helpers.tpl new file mode 100644 index 0000000000..2d4272ca92 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/_components/app-proxy/_helpers.tpl @@ -0,0 +1,43 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "app-proxy.name" -}} + {{- printf "%s-%s" (include "cf-runtime.name" .) "app-proxy" | 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 "app-proxy.fullname" -}} + {{- printf "%s-%s" (include "cf-runtime.fullname" .) "app-proxy" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "app-proxy.labels" -}} +{{ include "cf-runtime.labels" . }} +codefresh.io/application: app-proxy +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "app-proxy.selectorLabels" -}} +{{ include "cf-runtime.selectorLabels" . }} +codefresh.io/application: app-proxy +{{- end }} + + +{{/* +Create the name of the service account to use +*/}} +{{- define "app-proxy.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "app-proxy.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/_components/app-proxy/_ingress.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/_components/app-proxy/_ingress.yaml new file mode 100644 index 0000000000..d7860b3638 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/_components/app-proxy/_ingress.yaml @@ -0,0 +1,32 @@ +{{- define "app-proxy.resources.ingress" -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "app-proxy.fullname" . }} + labels: {{- include "app-proxy.labels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if and .Values.ingress.class (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }} + ingressClassName: {{ .Values.ingress.class }} + {{- end }} + {{- if .Values.ingress.tlsSecret }} + tls: + - hosts: + - {{ .Values.ingress.host }} + secretName: {{ .Values.tlsSecret }} + {{- end }} + rules: + - host: {{ .Values.ingress.host }} + http: + paths: + - path: {{ .Values.ingress.pathPrefix | default "/" }} + pathType: ImplementationSpecific + backend: + service: + name: {{ include "app-proxy.fullname" . }} + port: + number: 80 +{{- end -}} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/_components/app-proxy/_rbac.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/_components/app-proxy/_rbac.yaml new file mode 100644 index 0000000000..87bd869ba0 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/_components/app-proxy/_rbac.yaml @@ -0,0 +1,47 @@ +{{- define "app-proxy.resources.rbac" -}} +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "app-proxy.serviceAccountName" . }} + labels: + {{- include "app-proxy.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} +--- +{{- if .Values.rbac.create }} +kind: {{ .Values.rbac.namespaced | ternary "Role" "ClusterRole" }} +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "app-proxy.fullname" . }} + labels: + {{- include "app-proxy.labels" . | nindent 4 }} +rules: + - apiGroups: [ "" ] + resources: [ "secrets" ] + verbs: [ "get" ] +{{- with .Values.rbac.rules }} + {{ toYaml . | nindent 2 }} +{{- end }} +{{- end }} +--- +{{- if and .Values.serviceAccount.create .Values.rbac.create }} +kind: {{ .Values.rbac.namespaced | ternary "RoleBinding" "ClusterRoleBinding" }} +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "app-proxy.fullname" . }} + labels: + {{- include "app-proxy.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ include "app-proxy.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: Role + name: {{ include "app-proxy.fullname" . }} + apiGroup: rbac.authorization.k8s.io +{{- end }} +{{- end -}} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/_components/app-proxy/_service.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/_components/app-proxy/_service.yaml new file mode 100644 index 0000000000..4c3a93bf27 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/_components/app-proxy/_service.yaml @@ -0,0 +1,17 @@ +{{- define "app-proxy.resources.service" -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "app-proxy.fullname" . }} + labels: + {{- include "app-proxy.labels" . | nindent 4 }} +spec: + type: ClusterIP + ports: + - name: http + port: 80 + protocol: TCP + targetPort: 3000 + selector: + {{- include "app-proxy.selectorLabels" . | nindent 4 }} +{{- end -}} \ No newline at end of file diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/_components/event-exporter/_deployment.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/_components/event-exporter/_deployment.yaml new file mode 100644 index 0000000000..62588b4d3d --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/_components/event-exporter/_deployment.yaml @@ -0,0 +1,62 @@ +{{- define "event-exporter.resources.deployment" -}} +{{ $cfCommonTplSemver := printf "cf-common-%s" (index .Subcharts "cf-common").Chart.Version }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "event-exporter.fullname" . }} + labels: + {{- include "event-exporter.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.replicasCount }} + strategy: + type: {{ .Values.updateStrategy.type }} + selector: + matchLabels: + {{- include "event-exporter.selectorLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "event-exporter.selectorLabels" . | nindent 8 }} + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- include (printf "%s.image.pullSecrets" $cfCommonTplSemver ) . | nindent 8 }} + serviceAccountName: {{ include "event-exporter.serviceAccountName" . }} + {{- if .Values.podSecurityContext.enabled }} + securityContext: {{- omit .Values.podSecurityContext "enabled" | toYaml | nindent 8 }} + {{- end }} + containers: + - name: event-exporter + image: {{ include (printf "%s.image.name" $cfCommonTplSemver ) (dict "image" .Values.image "context" .) }} + imagePullPolicy: {{ .Values.image.pullPolicy | default "Always" }} + args: [--running-in-cluster=true] + env: + {{- include "event-exporter.environment-variables" . | nindent 8 }} + ports: + - name: metrics + containerPort: 9102 + resources: + {{- toYaml .Values.resources | nindent 12 }} + volumeMounts: + {{- with .Values.extraVolumeMounts }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 6 }} + {{- end }} + volumes: + {{- with .Values.extraVolumes }} + {{- toYaml . | nindent 6 }} + {{- end }} +{{- end -}} \ No newline at end of file diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/_components/event-exporter/_env-vars.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/_components/event-exporter/_env-vars.yaml new file mode 100644 index 0000000000..d28d0776f3 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/_components/event-exporter/_env-vars.yaml @@ -0,0 +1,14 @@ +{{- define "event-exporter.environment-variables.defaults" }} +{{- end }} + +{{- define "event-exporter.environment-variables.calculated" }} +{{- end }} + +{{- define "event-exporter.environment-variables" }} +{{- $cfCommonTplSemver := printf "cf-common-%s" (index .Subcharts "cf-common").Chart.Version }} +{{- $defaults := (include "event-exporter.environment-variables.defaults" . | fromYaml) }} +{{- $calculated := (include "event-exporter.environment-variables.calculated" . | fromYaml) }} +{{- $overrides := .Values.env }} +{{- $mergedValues := mergeOverwrite (merge $defaults $calculated) $overrides }} +{{- include (printf "%s.env-vars" $cfCommonTplSemver) (dict "Values" $mergedValues "context" .) }} +{{- end }} \ No newline at end of file diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/_components/event-exporter/_helpers.tpl b/charts/codefresh/cf-runtime/6.4.1/templates/_components/event-exporter/_helpers.tpl new file mode 100644 index 0000000000..5b8b5eff7f --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/_components/event-exporter/_helpers.tpl @@ -0,0 +1,43 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "event-exporter.name" -}} + {{- printf "%s-%s" (include "cf-runtime.name" .) "event-exporter" | 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 "event-exporter.fullname" -}} + {{- printf "%s-%s" (include "cf-runtime.fullname" .) "event-exporter" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "event-exporter.labels" -}} +{{ include "cf-runtime.labels" . }} +app: event-exporter +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "event-exporter.selectorLabels" -}} +{{ include "cf-runtime.selectorLabels" . }} +app: event-exporter +{{- end }} + + +{{/* +Create the name of the service account to use +*/}} +{{- define "event-exporter.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "event-exporter.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/_components/event-exporter/_rbac.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/_components/event-exporter/_rbac.yaml new file mode 100644 index 0000000000..69d7b6b2fb --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/_components/event-exporter/_rbac.yaml @@ -0,0 +1,47 @@ +{{- define "event-exporter.resources.rbac" -}} +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "event-exporter.serviceAccountName" . }} + labels: + {{- include "event-exporter.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} +--- +{{- if .Values.rbac.create }} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "event-exporter.fullname" . }} + labels: + {{- include "event-exporter.labels" . | nindent 4 }} +rules: + - apiGroups: [""] + resources: [events] + verbs: [get, list, watch] +{{- with .Values.rbac.rules }} + {{ toYaml . | nindent 2 }} +{{- end }} +{{- end }} +--- +{{- if and .Values.serviceAccount.create .Values.rbac.create }} +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "event-exporter.fullname" . }} + labels: + {{- include "event-exporter.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ include "event-exporter.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: {{ include "event-exporter.fullname" . }} + apiGroup: rbac.authorization.k8s.io +{{- end }} +{{- end -}} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/_components/event-exporter/_service.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/_components/event-exporter/_service.yaml new file mode 100644 index 0000000000..6fa29ec1a0 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/_components/event-exporter/_service.yaml @@ -0,0 +1,17 @@ +{{- define "event-exporter.resources.service" -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "event-exporter.fullname" . }} + labels: + {{- include "event-exporter.labels" . | nindent 4 }} +spec: + type: ClusterIP + ports: + - name: metrics + port: 9102 + targetPort: metrics + protocol: TCP + selector: + {{- include "event-exporter.selectorLabels" . | nindent 4 }} +{{- end -}} \ No newline at end of file diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/_components/event-exporter/_serviceMontor.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/_components/event-exporter/_serviceMontor.yaml new file mode 100644 index 0000000000..6092443f0a --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/_components/event-exporter/_serviceMontor.yaml @@ -0,0 +1,14 @@ +{{- define "event-exporter.resources.serviceMonitor" -}} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "event-exporter.fullname" . }} + labels: + {{- include "event-exporter.labels" . | nindent 4 }} +spec: + endpoints: + - port: metrics + selector: + matchLabels: + {{- include "event-exporter.selectorLabels" . | nindent 6 }} +{{- end -}} \ No newline at end of file diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/_components/monitor/_deployment.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/_components/monitor/_deployment.yaml new file mode 100644 index 0000000000..7efa6557b1 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/_components/monitor/_deployment.yaml @@ -0,0 +1,70 @@ +{{- define "monitor.resources.deployment" -}} +{{ $cfCommonTplSemver := printf "cf-common-%s" (index .Subcharts "cf-common").Chart.Version }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "monitor.fullname" . }} + labels: + {{- include "monitor.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.replicasCount }} + strategy: + type: {{ .Values.updateStrategy.type }} + selector: + matchLabels: + {{- include "monitor.selectorLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "monitor.selectorLabels" . | nindent 8 }} + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- include (printf "%s.image.pullSecrets" $cfCommonTplSemver ) . | nindent 8 }} + serviceAccountName: {{ include "monitor.serviceAccountName" . }} + {{- if .Values.podSecurityContext.enabled }} + securityContext: {{- omit .Values.podSecurityContext "enabled" | toYaml | nindent 8 }} + {{- end }} + containers: + - name: monitor + image: {{ include (printf "%s.image.name" $cfCommonTplSemver ) (dict "image" .Values.image "context" .) }} + imagePullPolicy: {{ .Values.image.pullPolicy | default "Always" }} + env: + {{- include "monitor.environment-variables" . | nindent 8 }} + ports: + - name: http + containerPort: 9020 + readinessProbe: + initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.readinessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }} + successThreshold: {{ .Values.readinessProbe.successThreshold }} + failureThreshold: {{ .Values.readinessProbe.failureThreshold }} + httpGet: + path: /api/ping + port: 9020 + resources: + {{- toYaml .Values.resources | nindent 12 }} + volumeMounts: + {{- with .Values.extraVolumeMounts }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 6 }} + {{- end }} + volumes: + {{- with .Values.extraVolumes }} + {{- toYaml . | nindent 6 }} + {{- end }} +{{- end -}} \ No newline at end of file diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/_components/monitor/_env-vars.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/_components/monitor/_env-vars.yaml new file mode 100644 index 0000000000..f58c7fa250 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/_components/monitor/_env-vars.yaml @@ -0,0 +1,26 @@ +{{- define "monitor.environment-variables.defaults" }} +SERVICE_NAME: {{ include "monitor.fullname" . }} +PORT: 9020 +HELM3: true +NODE_OPTIONS: "--max_old_space_size=4096" +{{- end }} + +{{- define "monitor.environment-variables.calculated" }} +API_TOKEN: {{ include "runtime.installation-token-env-var-value" . | nindent 2 }} +CLUSTER_ID: {{ include "runtime.runtime-environment-spec.context-name" . }} +API_URL: {{ include "runtime.runtime-environment-spec.codefresh-host" . }}/api/k8s-monitor/events +ACCOUNT_ID: {{ .Values.global.accountId }} +NAMESPACE: {{ .Release.Namespace }} +{{- if .Values.rbac.namespaced }} +ROLE_BINDING: true +{{- end }} +{{- end }} + +{{- define "monitor.environment-variables" }} +{{- $cfCommonTplSemver := printf "cf-common-%s" (index .Subcharts "cf-common").Chart.Version }} +{{- $defaults := (include "monitor.environment-variables.defaults" . | fromYaml) }} +{{- $calculated := (include "monitor.environment-variables.calculated" . | fromYaml) }} +{{- $overrides := .Values.env }} +{{- $mergedValues := mergeOverwrite (merge $defaults $calculated) $overrides }} +{{- include (printf "%s.env-vars" $cfCommonTplSemver) (dict "Values" $mergedValues "context" .) }} +{{- end }} \ No newline at end of file diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/_components/monitor/_helpers.tpl b/charts/codefresh/cf-runtime/6.4.1/templates/_components/monitor/_helpers.tpl new file mode 100644 index 0000000000..71cc1c027d --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/_components/monitor/_helpers.tpl @@ -0,0 +1,42 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "monitor.name" -}} + {{- printf "%s-%s" (include "cf-runtime.name" .) "monitor" | 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 "monitor.fullname" -}} + {{- printf "%s-%s" (include "cf-runtime.fullname" .) "monitor" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "monitor.labels" -}} +{{ include "cf-runtime.labels" . }} +codefresh.io/application: monitor +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "monitor.selectorLabels" -}} +{{ include "cf-runtime.selectorLabels" . }} +codefresh.io/application: monitor +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "monitor.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "monitor.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/_components/monitor/_rbac.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/_components/monitor/_rbac.yaml new file mode 100644 index 0000000000..88204796ae --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/_components/monitor/_rbac.yaml @@ -0,0 +1,56 @@ +{{- define "monitor.resources.rbac" -}} +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "monitor.serviceAccountName" . }} + labels: + {{- include "monitor.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} +--- +{{- if .Values.rbac.create }} +kind: {{ .Values.rbac.namespaced | ternary "Role" "ClusterRole" }} +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "monitor.fullname" . }} + labels: + {{- include "monitor.labels" . | nindent 4 }} +rules: + - apiGroups: [ "" ] + resources: [ "*" ] + verbs: [ "get", "list", "watch", "create", "delete" ] + - apiGroups: [ "" ] + resources: [ "pods" ] + verbs: [ "get", "list", "watch", "create", "deletecollection" ] + - apiGroups: [ "extensions" ] + resources: [ "*" ] + verbs: [ "get", "list", "watch" ] + - apiGroups: [ "apps" ] + resources: [ "*" ] + verbs: [ "get", "list", "watch" ] +{{- with .Values.rbac.rules }} + {{ toYaml . | nindent 2 }} +{{- end }} +{{- end }} +--- +{{- if and .Values.serviceAccount.create .Values.rbac.create }} +kind: {{ .Values.rbac.namespaced | ternary "RoleBinding" "ClusterRoleBinding" }} +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "monitor.fullname" . }} + labels: + {{- include "monitor.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ include "monitor.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: {{ .Values.rbac.namespaced | ternary "Role" "ClusterRole" }} + name: {{ include "monitor.fullname" . }} + apiGroup: rbac.authorization.k8s.io +{{- end }} +{{- end -}} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/_components/monitor/_service.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/_components/monitor/_service.yaml new file mode 100644 index 0000000000..f6ae9bb0f7 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/_components/monitor/_service.yaml @@ -0,0 +1,17 @@ +{{- define "monitor.resources.service" -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "monitor.fullname" . }} + labels: + {{- include "monitor.labels" . | nindent 4 }} +spec: + type: ClusterIP + ports: + - name: http + port: 80 + protocol: TCP + targetPort: 9020 + selector: + {{- include "monitor.selectorLabels" . | nindent 4 }} +{{- end -}} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/_components/runner/_deployment.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/_components/runner/_deployment.yaml new file mode 100644 index 0000000000..e1fb9439ab --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/_components/runner/_deployment.yaml @@ -0,0 +1,103 @@ +{{- define "runner.resources.deployment" -}} +{{ $cfCommonTplSemver := printf "cf-common-%s" (index .Subcharts "cf-common").Chart.Version }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "runner.fullname" . }} + labels: + {{- include "runner.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.replicasCount }} + strategy: + type: {{ .Values.updateStrategy.type }} + selector: + matchLabels: + {{- include "runner.selectorLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "runner.selectorLabels" . | nindent 8 }} + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- include (printf "%s.image.pullSecrets" $cfCommonTplSemver ) . | nindent 8 }} + serviceAccountName: {{ include "runner.serviceAccountName" . }} + {{- if .Values.podSecurityContext.enabled }} + securityContext: {{- omit .Values.podSecurityContext "enabled" | toYaml | nindent 8 }} + {{- end }} + initContainers: + - name: init + image: {{ include (printf "%s.image.name" $cfCommonTplSemver ) (dict "image" .Values.init.image "context" .) }} + imagePullPolicy: {{ .Values.init.image.pullPolicy | default "IfNotPresent" }} + command: + - /bin/bash + args: + - -ec + - | {{ .Files.Get "files/init-runtime.sh" | nindent 10 }} + env: + {{- include "runner-init.environment-variables" . | nindent 8 }} + {{- with .Values.init.resources }} + resources: + {{- toYaml . | nindent 10 }} + {{- end }} + containers: + - name: runner + image: {{ include (printf "%s.image.name" $cfCommonTplSemver ) (dict "image" .Values.image "context" .) }} + imagePullPolicy: {{ .Values.image.pullPolicy | default "IfNotPresent" }} + env: + {{- include "runner.environment-variables" . | nindent 8 }} + ports: + - name: http + containerPort: 8080 + readinessProbe: + initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.readinessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }} + successThreshold: {{ .Values.readinessProbe.successThreshold }} + failureThreshold: {{ .Values.readinessProbe.failureThreshold }} + httpGet: + path: /health + port: http + {{- with .Values.resources }} + resources: + {{- toYaml . | nindent 10 }} + {{- end }} + {{- with .Values.extraVolumeMounts }} + volumeMounts: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.sidecar.enabled }} + - name: reconcile-runtime + image: {{ include (printf "%s.image.name" $cfCommonTplSemver ) (dict "image" .Values.sidecar.image "context" .) }} + imagePullPolicy: {{ .Values.sidecar.image.pullPolicy | default "IfNotPresent" }} + command: + - /bin/bash + args: + - -ec + - | {{ .Files.Get "files/reconcile-runtime.sh" | nindent 10 }} + env: + {{- include "runner-sidecar.environment-variables" . | nindent 8 }} + {{- with .Values.sidecar.resources }} + resources: + {{- toYaml . | nindent 10 }} + {{- end }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.extraVolumes }} + volumes: + {{- toYaml . | nindent 6 }} + {{- end }} +{{- end -}} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/_components/runner/_helpers.tpl b/charts/codefresh/cf-runtime/6.4.1/templates/_components/runner/_helpers.tpl new file mode 100644 index 0000000000..2608cb67ee --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/_components/runner/_helpers.tpl @@ -0,0 +1,42 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "runner.name" -}} + {{- printf "%s-%s" (include "cf-runtime.name" .) "runner" | 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 "runner.fullname" -}} + {{- printf "%s-%s" (include "cf-runtime.fullname" .) "runner" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "runner.labels" -}} +{{ include "cf-runtime.labels" . }} +codefresh.io/application: runner +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "runner.selectorLabels" -}} +{{ include "cf-runtime.selectorLabels" . }} +codefresh.io/application: runner +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "runner.serviceAccountName" -}} + {{- if .Values.serviceAccount.create }} + {{- default (include "runner.fullname" .) .Values.serviceAccount.name }} + {{- else }} + {{- default "default" .Values.serviceAccount.name }} + {{- end }} +{{- end }} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/_components/runner/_rbac.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/_components/runner/_rbac.yaml new file mode 100644 index 0000000000..d95b958d54 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/_components/runner/_rbac.yaml @@ -0,0 +1,53 @@ +{{- define "runner.resources.rbac" -}} +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "runner.serviceAccountName" . }} + labels: + {{- include "runner.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} +--- +{{- if .Values.rbac.create }} +kind: Role +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "runner.fullname" . }} + labels: + {{- include "runner.labels" . | nindent 4 }} +rules: + - apiGroups: [ "" ] + resources: [ "pods", "persistentvolumeclaims" ] + verbs: [ "get", "create", "delete", patch ] + - apiGroups: [ "" ] + resources: [ "configmaps", "secrets" ] + verbs: [ "get", "create", "update", patch ] + - apiGroups: [ "apps" ] + resources: [ "deployments" ] + verbs: [ "get" ] +{{- with .Values.rbac.rules }} + {{ toYaml . | nindent 2 }} +{{- end }} +{{- end }} +--- +{{- if and .Values.serviceAccount.create .Values.rbac.create }} +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "runner.fullname" . }} + labels: + {{- include "runner.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ include "runner.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: Role + name: {{ include "runner.fullname" . }} + apiGroup: rbac.authorization.k8s.io +{{- end }} +{{- end -}} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/_components/runner/environment-variables/_init-container.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/_components/runner/environment-variables/_init-container.yaml new file mode 100644 index 0000000000..6dda110f78 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/_components/runner/environment-variables/_init-container.yaml @@ -0,0 +1,30 @@ +{{- define "runner-init.environment-variables.defaults" }} +HOME: /tmp +{{- end }} + +{{- define "runner-init.environment-variables.calculated" }} +AGENT_NAME: {{ include "runtime.runtime-environment-spec.agent-name" . }} +API_HOST: {{ include "runtime.runtime-environment-spec.codefresh-host" . }} +AGENT_CODEFRESH_TOKEN: + valueFrom: + secretKeyRef: + name: {{ include "runner.fullname" . }} + key: agent-codefresh-token + optional: true +EXISTING_AGENT_CODEFRESH_TOKEN: {{ include "runtime.agent-token-env-var-value" . | nindent 2 }} +KUBE_CONTEXT: {{ include "runtime.runtime-environment-spec.context-name" . }} +KUBE_NAMESPACE: {{ .Release.Namespace }} +OWNER_NAME: {{ include "runner.fullname" . }} +RUNTIME_NAME: {{ include "runtime.runtime-environment-spec.runtime-name" . }} +SECRET_NAME: {{ include "runner.fullname" . }} +USER_CODEFRESH_TOKEN: {{ include "runtime.installation-token-env-var-value" . | nindent 2 }} +{{- end }} + +{{- define "runner-init.environment-variables" }} + {{- $cfCommonTplSemver := printf "cf-common-%s" (index .Subcharts "cf-common").Chart.Version }} + {{- $defaults := (include "runner-init.environment-variables.defaults" . | fromYaml) }} + {{- $calculated := (include "runner-init.environment-variables.calculated" . | fromYaml) }} + {{- $overrides := .Values.env }} + {{- $mergedValues := mergeOverwrite (merge $defaults $calculated) $overrides }} + {{- include (printf "%s.env-vars" $cfCommonTplSemver) (dict "Values" $mergedValues "context" .) }} +{{- end }} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/_components/runner/environment-variables/_main-container.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/_components/runner/environment-variables/_main-container.yaml new file mode 100644 index 0000000000..4d3f0304e2 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/_components/runner/environment-variables/_main-container.yaml @@ -0,0 +1,28 @@ +{{- define "runner.environment-variables.defaults" }} +AGENT_MODE: InCluster +SELF_DEPLOYMENT_NAME: + valueFrom: + fieldRef: + fieldPath: metadata.name +{{- end }} + +{{- define "runner.environment-variables.calculated" }} +AGENT_ID: {{ include "runtime.runtime-environment-spec.agent-name" . }} +CODEFRESH_HOST: {{ include "runtime.runtime-environment-spec.codefresh-host" . }} +CODEFRESH_IN_CLUSTER_RUNTIME: {{ include "runtime.runtime-environment-spec.runtime-name" . }} +CODEFRESH_TOKEN: + valueFrom: + secretKeyRef: + name: {{ include "runner.fullname" . }} + key: agent-codefresh-token +DOCKER_REGISTRY: {{ .Values.global.imageRegistry }} +{{- end }} + +{{- define "runner.environment-variables" }} +{{- $cfCommonTplSemver := printf "cf-common-%s" (index .Subcharts "cf-common").Chart.Version }} +{{- $defaults := (include "runner.environment-variables.defaults" . | fromYaml) }} +{{- $calculated := (include "runner.environment-variables.calculated" . | fromYaml) }} +{{- $overrides := .Values.env }} +{{- $mergedValues := mergeOverwrite (merge $defaults $calculated) $overrides }} +{{- include (printf "%s.env-vars" $cfCommonTplSemver) (dict "Values" $mergedValues "context" .) }} +{{- end }} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/_components/runner/environment-variables/_sidecar-container.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/_components/runner/environment-variables/_sidecar-container.yaml new file mode 100644 index 0000000000..3adcbe5d49 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/_components/runner/environment-variables/_sidecar-container.yaml @@ -0,0 +1,22 @@ +{{- define "runner-sidecar.environment-variables.defaults" }} +HOME: /tmp +{{- end }} + +{{- define "runner-sidecar.environment-variables.calculated" }} +API_HOST: {{ include "runtime.runtime-environment-spec.codefresh-host" . }} +USER_CODEFRESH_TOKEN: {{ include "runtime.installation-token-env-var-value" . | nindent 2 }} +KUBE_CONTEXT: {{ include "runtime.runtime-environment-spec.context-name" . }} +KUBE_NAMESPACE: {{ .Release.Namespace }} +OWNER_NAME: {{ include "runner.fullname" . }} +RUNTIME_NAME: {{ include "runtime.runtime-environment-spec.runtime-name" . }} +CONFIGMAP_NAME: {{ printf "%s-%s" (include "runtime.fullname" .) "spec" }} +{{- end }} + +{{- define "runner-sidecar.environment-variables" }} + {{- $cfCommonTplSemver := printf "cf-common-%s" (index .Subcharts "cf-common").Chart.Version }} + {{- $defaults := (include "runner-sidecar.environment-variables.defaults" . | fromYaml) }} + {{- $calculated := (include "runner-sidecar.environment-variables.calculated" . | fromYaml) }} + {{- $overrides := .Values.sidecar.env }} + {{- $mergedValues := mergeOverwrite (merge $defaults $calculated) $overrides }} + {{- include (printf "%s.env-vars" $cfCommonTplSemver) (dict "Values" $mergedValues "context" .) }} +{{- end }} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/_components/volume-provisioner/_cronjob.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/_components/volume-provisioner/_cronjob.yaml new file mode 100644 index 0000000000..20bd2d56e1 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/_components/volume-provisioner/_cronjob.yaml @@ -0,0 +1,58 @@ +{{- define "dind-volume-provisioner.resources.cronjob" -}} +{{ $cfCommonTplSemver := printf "cf-common-%s" (index .Subcharts "cf-common").Chart.Version }} +{{- if not (eq .Values.storage.backend "local") }} +apiVersion: batch/v1 +kind: CronJob +metadata: + name: {{ include "dind-volume-cleanup.fullname" . }} + labels: + {{- include "dind-volume-cleanup.labels" . | nindent 4 }} +spec: + concurrencyPolicy: {{ .Values.concurrencyPolicy }} + schedule: {{ .Values.schedule | quote }} + successfulJobsHistoryLimit: {{ .Values.successfulJobsHistory }} + failedJobsHistoryLimit: {{ .Values.failedJobsHistory }} + {{- with .Values.suspend }} + suspend: {{ . }} + {{- end }} + jobTemplate: + spec: + template: + metadata: + labels: + {{- include "dind-volume-cleanup.selectorLabels" . | nindent 12 }} + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 12 }} + {{- end }} + spec: + {{- include (printf "%s.image.pullSecrets" $cfCommonTplSemver ) . | nindent 10 }} + serviceAccountName: {{ include "dind-volume-provisioner.serviceAccountName" . }} + {{- if .Values.podSecurityContext.enabled }} + securityContext: {{- omit .Values.podSecurityContext "enabled" | toYaml | nindent 12 }} + {{- end }} + restartPolicy: {{ .Values.restartPolicy | default "Never" }} + containers: + - name: dind-volume-cleanup + image: {{ include (printf "%s.image.name" $cfCommonTplSemver ) (dict "image" .Values.image "context" .) }} + imagePullPolicy: {{ .Values.image.pullPolicy | default "Always" }} + env: + {{- include (printf "%s.env-vars" $cfCommonTplSemver) (dict "Values" .Values.env "context" .) | nindent 12 }} + - name: PROVISIONED_BY + value: {{ include "dind-volume-provisioner.volumeProvisionerName" . }} + resources: + {{- toYaml .Values.resources | nindent 14 }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 10 }} + {{- end }} + {{- end }} +{{- end -}} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/_components/volume-provisioner/_daemonset.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/_components/volume-provisioner/_daemonset.yaml new file mode 100644 index 0000000000..cb463231d2 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/_components/volume-provisioner/_daemonset.yaml @@ -0,0 +1,98 @@ +{{- define "dind-volume-provisioner.resources.daemonset" -}} +{{ $cfCommonTplSemver := printf "cf-common-%s" (index .Subcharts "cf-common").Chart.Version }} +{{ $localVolumeParentDir := .Values.storage.local.volumeParentDir }} +{{- if eq .Values.storage.backend "local" }} +--- +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ include "dind-lv-monitor.fullname" . }} + labels: + {{- include "dind-lv-monitor.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "dind-lv-monitor.selectorLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "dind-lv-monitor.selectorLabels" . | nindent 8 }} + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- include (printf "%s.image.pullSecrets" $cfCommonTplSemver ) . | nindent 8 }} + serviceAccountName: {{ include "dind-volume-provisioner.serviceAccountName" . }} + {{- if .Values.podSecurityContext.enabled }} + securityContext: {{- omit .Values.podSecurityContext "enabled" | toYaml | nindent 8 }} + {{- end }} + {{- if .Values.volumePermissions.enabled }} + initContainers: + - name: volume-permissions + image: {{ include (printf "%s.image.name" $cfCommonTplSemver ) (dict "image" .Values.volumePermissions.image "context" .) }} + imagePullPolicy: {{ .Values.volumePermissions.image.pullPolicy | default "Always" }} + command: + - /bin/sh + args: + - -ec + - | + chown -R {{ .Values.podSecurityContext.runAsUser }}:{{ .Values.podSecurityContext.fsGroup }} {{ $localVolumeParentDir }} + volumeMounts: + - mountPath: {{ $localVolumeParentDir }} + name: dind-volume-dir + {{- if eq ( toString ( .Values.volumePermissions.securityContext.runAsUser )) "auto" }} + securityContext: {{- omit .Values.volumePermissions.securityContext "runAsUser" | toYaml | nindent 10 }} + {{- else }} + securityContext: {{- .Values.volumePermissions.securityContext | toYaml | nindent 10 }} + {{- end }} + resources: + {{- toYaml .Values.volumePermissions.resources | nindent 10 }} + {{- end }} + containers: + - name: dind-lv-monitor + image: {{ include (printf "%s.image.name" $cfCommonTplSemver ) (dict "image" .Values.image "context" .) }} + imagePullPolicy: {{ .Values.image.pullPolicy | default "Always" }} + {{- if .Values.containerSecurityContext.enabled }} + securityContext: {{- omit .Values.containerSecurityContext "enabled" | toYaml | nindent 10 }} + {{- end }} + command: + - /home/dind-volume-utils/bin/local-volumes-agent + env: + {{- include (printf "%s.env-vars" $cfCommonTplSemver) (dict "Values" .Values.env "context" .) | nindent 10 }} + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: VOLUME_PARENT_DIR + value: {{ $localVolumeParentDir }} + resources: + {{- toYaml .Values.resources | nindent 10 }} + volumeMounts: + - mountPath: {{ $localVolumeParentDir }} + readOnly: false + name: dind-volume-dir + {{- with .Values.extraVolumeMounts }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 6 }} + {{- end }} + volumes: + - name: dind-volume-dir + hostPath: + path: {{ $localVolumeParentDir }} + {{- with .Values.extraVolumes }} + {{- toYaml . | nindent 6 }} + {{- end }} +{{- end }} +{{- end -}} \ No newline at end of file diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/_components/volume-provisioner/_deployment.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/_components/volume-provisioner/_deployment.yaml new file mode 100644 index 0000000000..9252b45200 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/_components/volume-provisioner/_deployment.yaml @@ -0,0 +1,67 @@ +{{- define "dind-volume-provisioner.resources.deployment" -}} +{{ $cfCommonTplSemver := printf "cf-common-%s" (index .Subcharts "cf-common").Chart.Version }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "dind-volume-provisioner.fullname" . }} + labels: + {{- include "dind-volume-provisioner.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.replicasCount }} + strategy: + type: {{ .Values.updateStrategy.type }} + selector: + matchLabels: + {{- include "dind-volume-provisioner.selectorLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "dind-volume-provisioner.selectorLabels" . | nindent 8 }} + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- include (printf "%s.image.pullSecrets" $cfCommonTplSemver ) . | nindent 8 }} + serviceAccountName: {{ include "dind-volume-provisioner.serviceAccountName" . }} + {{- if .Values.podSecurityContext.enabled }} + securityContext: {{- omit .Values.podSecurityContext "enabled" | toYaml | nindent 8 }} + {{- end }} + containers: + - name: dind-volume-provisioner + image: {{ include (printf "%s.image.name" $cfCommonTplSemver ) (dict "image" .Values.image "context" .) }} + imagePullPolicy: {{ .Values.image.pullPolicy | default "Always" }} + command: + - /usr/local/bin/dind-volume-provisioner + - -v=4 + - --resync-period=50s + env: + {{- include "dind-volume-provisioner.environment-variables" . | nindent 8 }} + ports: + - name: http + containerPort: 8080 + resources: + {{- toYaml .Values.resources | nindent 12 }} + volumeMounts: + {{- include "dind-volume-provisioner.volumeMounts.calculated" . | nindent 8 }} + {{- with .Values.extraVolumeMounts }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 6 }} + {{- end }} + volumes: + {{- include "dind-volume-provisioner.volumes.calculated" . | nindent 6 }} + {{- with .Values.extraVolumes }} + {{- toYaml . | nindent 6 }} + {{- end }} +{{- end -}} \ No newline at end of file diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/_components/volume-provisioner/_env-vars.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/_components/volume-provisioner/_env-vars.yaml new file mode 100644 index 0000000000..e1f5dfe603 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/_components/volume-provisioner/_env-vars.yaml @@ -0,0 +1,88 @@ +{{- define "dind-volume-provisioner.environment-variables.defaults" }} +{{- end }} + +{{- define "dind-volume-provisioner.environment-variables.calculated" }} +DOCKER_REGISTRY: {{ .Values.global.imageRegistry }} +PROVISIONER_NAME: {{ include "dind-volume-provisioner.volumeProvisionerName" . }} + +{{- if or .Values.storage.ebs.accessKeyId .Values.storage.ebs.accessKeyIdSecretKeyRef }} +AWS_ACCESS_KEY_ID: + {{- if .Values.storage.ebs.accessKeyId }} + valueFrom: + secretKeyRef: + name: {{ include "dind-volume-provisioner.fullname" . }} + key: aws_access_key_id + {{- else if .Values.storage.ebs.accessKeyIdSecretKeyRef }} + valueFrom: + secretKeyRef: + {{- .Values.storage.ebs.accessKeyIdSecretKeyRef | toYaml | nindent 6 }} + {{- end }} +{{- end }} + +{{- if or .Values.storage.ebs.secretAccessKey .Values.storage.ebs.secretAccessKeySecretKeyRef }} +AWS_SECRET_ACCESS_KEY: + {{- if .Values.storage.ebs.secretAccessKey }} + valueFrom: + secretKeyRef: + name: {{ include "dind-volume-provisioner.fullname" . }} + key: aws_secret_access_key + {{- else if .Values.storage.ebs.secretAccessKeySecretKeyRef }} + valueFrom: + secretKeyRef: + {{- .Values.storage.ebs.secretAccessKeySecretKeyRef | toYaml | nindent 6 }} + {{- end }} +{{- end }} + +{{- if or .Values.storage.gcedisk.serviceAccountJson .Values.storage.gcedisk.serviceAccountJsonSecretKeyRef }} +GOOGLE_APPLICATION_CREDENTIALS: {{ printf "/etc/dind-volume-provisioner/credentials/%s" (.Values.storage.gcedisk.serviceAccountJsonSecretKeyRef.key | default "google-service-account.json") }} +{{- end }} + +{{- if and .Values.storage.mountAzureJson }} +AZURE_CREDENTIAL_FILE: /etc/kubernetes/azure.json +CLOUDCONFIG_AZURE: /etc/kubernetes/azure.json +{{- end }} + +{{- end }} + +{{- define "dind-volume-provisioner.environment-variables" }} +{{- $cfCommonTplSemver := printf "cf-common-%s" (index .Subcharts "cf-common").Chart.Version }} +{{- $defaults := (include "dind-volume-provisioner.environment-variables.defaults" . | fromYaml) }} +{{- $calculated := (include "dind-volume-provisioner.environment-variables.calculated" . | fromYaml) }} +{{- $overrides := .Values.env }} +{{- $mergedValues := mergeOverwrite (merge $defaults $calculated) $overrides }} +{{- include (printf "%s.env-vars" $cfCommonTplSemver) (dict "Values" $mergedValues "context" .) }} +{{- end }} + + +{{- define "dind-volume-provisioner.volumes.calculated" }} + {{- if .Values.storage.gcedisk.serviceAccountJson }} +- name: credentials + secret: + secretName: {{ include "dind-volume-provisioner.fullname" . }} + optional: true + {{- else if .Values.storage.gcedisk.serviceAccountJsonSecretKeyRef }} +- name: credentials + secret: + secretName: {{ .Values.storage.gcedisk.serviceAccountJsonSecretKeyRef.name }} + optional: true + {{- end }} + {{- if .Values.storage.mountAzureJson }} +- name: azure-json + hostPath: + path: /etc/kubernetes/azure.json + type: File + {{- end }} +{{- end }} + +{{- define "dind-volume-provisioner.volumeMounts.calculated" }} + {{- if or .Values.storage.gcedisk.serviceAccountJson .Values.storage.gcedisk.serviceAccountJsonSecretKeyRef }} +- name: credentials + readOnly: true + mountPath: "/etc/dind-volume-provisioner/credentials" + {{- end }} + {{- if .Values.storage.mountAzureJson }} +- name: azure-json + readOnly: true + mountPath: "/etc/kubernetes/azure.json" + {{- end }} +{{- end }} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/_components/volume-provisioner/_helpers.tpl b/charts/codefresh/cf-runtime/6.4.1/templates/_components/volume-provisioner/_helpers.tpl new file mode 100644 index 0000000000..e3d3a0d3f7 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/_components/volume-provisioner/_helpers.tpl @@ -0,0 +1,93 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "dind-volume-provisioner.name" -}} + {{- printf "%s-%s" (include "cf-runtime.name" .) "volume-provisioner" | 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 "dind-volume-provisioner.fullname" -}} + {{- printf "%s-%s" (include "cf-runtime.fullname" .) "volume-provisioner" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{- define "dind-volume-cleanup.fullname" -}} + {{- printf "%s-%s" (include "cf-runtime.fullname" .) "volume-cleanup" | trunc 52 | trimSuffix "-" }} +{{- end }} + +{{- define "dind-lv-monitor.fullname" -}} + {{- printf "%s-%s" (include "cf-runtime.fullname" .) "lv-monitor" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Provisioner name for storage class +*/}} +{{- define "dind-volume-provisioner.volumeProvisionerName" }} + {{- printf "codefresh.io/dind-volume-provisioner-runner-%s" .Release.Namespace }} +{{- end }} + +{{/* +Common labels for dind-lv-monitor +*/}} +{{- define "dind-lv-monitor.labels" -}} +{{ include "cf-runtime.labels" . }} +codefresh.io/application: lv-monitor +{{- end }} + +{{/* +Selector labels for dind-lv-monitor +*/}} +{{- define "dind-lv-monitor.selectorLabels" -}} +{{ include "cf-runtime.selectorLabels" . }} +codefresh.io/application: lv-monitor +{{- end }} + +{{/* +Common labels for dind-volume-provisioner +*/}} +{{- define "dind-volume-provisioner.labels" -}} +{{ include "cf-runtime.labels" . }} +codefresh.io/application: volume-provisioner +{{- end }} + +{{/* +Selector labels for dind-volume-provisioner +*/}} +{{- define "dind-volume-provisioner.selectorLabels" -}} +{{ include "cf-runtime.selectorLabels" . }} +codefresh.io/application: volume-provisioner +{{- end }} + +{{/* +Common labels for dind-volume-cleanup +*/}} +{{- define "dind-volume-cleanup.labels" -}} +{{ include "cf-runtime.labels" . }} +codefresh.io/application: pv-cleanup +{{- end }} + +{{/* +Common labels for dind-volume-cleanup +*/}} +{{- define "dind-volume-cleanup.selectorLabels" -}} +{{ include "cf-runtime.selectorLabels" . }} +codefresh.io/application: pv-cleanup +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "dind-volume-provisioner.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "dind-volume-provisioner.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{- define "dind-volume-provisioner.storageClassName" }} +{{- printf "dind-local-volumes-runner-%s" .Release.Namespace }} +{{- end }} \ No newline at end of file diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/_components/volume-provisioner/_rbac.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/_components/volume-provisioner/_rbac.yaml new file mode 100644 index 0000000000..fbcbc684fc --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/_components/volume-provisioner/_rbac.yaml @@ -0,0 +1,71 @@ +{{- define "dind-volume-provisioner.resources.rbac" -}} +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "dind-volume-provisioner.serviceAccountName" . }} + labels: + {{- include "dind-volume-provisioner.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} +--- +{{- if .Values.rbac.create }} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "dind-volume-provisioner.fullname" . }} + labels: + {{- include "dind-volume-provisioner.labels" . | nindent 4 }} +rules: + - apiGroups: [ "" ] + resources: [ "persistentvolumes" ] + verbs: [ "get", "list", "watch", "create", "delete", "patch" ] + - apiGroups: [ "" ] + resources: [ "persistentvolumeclaims" ] + verbs: [ "get", "list", "watch", "update", "delete" ] + - apiGroups: [ "storage.k8s.io" ] + resources: [ "storageclasses" ] + verbs: [ "get", "list", "watch" ] + - apiGroups: [ "" ] + resources: [ "events" ] + verbs: [ "list", "watch", "create", "update", "patch" ] + - apiGroups: [ "" ] + resources: [ "secrets" ] + verbs: [ "get", "list" ] + - apiGroups: [ "" ] + resources: [ "nodes" ] + verbs: [ "get", "list", "watch" ] + - apiGroups: [ "" ] + resources: [ "pods" ] + verbs: [ "get", "list", "watch", "create", "delete", "patch" ] + - apiGroups: [ "" ] + resources: [ "endpoints" ] + verbs: [ "get", "list", "watch", "create", "update", "delete" ] + - apiGroups: [ "coordination.k8s.io" ] + resources: [ "leases" ] + verbs: [ "get", "create", "update" ] +{{- with .Values.rbac.rules }} + {{ toYaml . | nindent 2 }} +{{- end }} +{{- end }} +--- +{{- if and .Values.serviceAccount.create .Values.rbac.create }} +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "dind-volume-provisioner.fullname" . }} + labels: + {{- include "dind-volume-provisioner.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ include "dind-volume-provisioner.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: {{ include "dind-volume-provisioner.fullname" . }} + apiGroup: rbac.authorization.k8s.io +{{- end }} +{{- end -}} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/_components/volume-provisioner/_secret.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/_components/volume-provisioner/_secret.yaml new file mode 100644 index 0000000000..f361a79910 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/_components/volume-provisioner/_secret.yaml @@ -0,0 +1,22 @@ +{{- define "dind-volume-provisioner.resources.secret" -}} +{{- if or .Values.storage.ebs.accessKeyId .Values.storage.ebs.secretAccessKey .Values.storage.gcedisk.serviceAccountJson }} +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + name: {{ include "dind-volume-provisioner.fullname" . }} + labels: + {{- include "dind-volume-provisioner.labels" . | nindent 4 }} +stringData: + {{- with .Values.storage.gcedisk.serviceAccountJson }} + google-service-account.json: | +{{- . | nindent 4 }} + {{- end }} + {{- with .Values.storage.ebs.accessKeyId }} + aws_access_key_id: {{ . }} + {{- end }} + {{- with .Values.storage.ebs.secretAccessKey }} + aws_secret_access_key: {{ . }} + {{- end }} +{{- end }} +{{- end -}} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/_components/volume-provisioner/_storageclass.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/_components/volume-provisioner/_storageclass.yaml new file mode 100644 index 0000000000..62e910c87e --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/_components/volume-provisioner/_storageclass.yaml @@ -0,0 +1,47 @@ +{{- define "dind-volume-provisioner.resources.storageclass" -}} +kind: StorageClass +apiVersion: storage.k8s.io/v1 +metadata: + {{/* has to be exactly that */}} + name: {{ include "dind-volume-provisioner.storageClassName" . }} + labels: + {{- include "dind-volume-provisioner.labels" . | nindent 4 }} +provisioner: {{ include "dind-volume-provisioner.volumeProvisionerName" . }} +parameters: +{{- if eq .Values.storage.backend "local" }} + volumeBackend: local + volumeParentDir: {{ .Values.storage.local.volumeParentDir }} +{{- else if eq .Values.storage.backend "gcedisk" }} + volumeBackend: {{ .Values.storage.backend }} + type: {{ .Values.storage.gcedisk.volumeType | default "pd-ssd" }} + zone: {{ required ".Values.storage.gcedisk.availabilityZone is required" .Values.storage.gcedisk.availabilityZone }} + fsType: {{ .Values.storage.fsType | default "ext4" }} +{{- else if or (eq .Values.storage.backend "ebs") (eq .Values.storage.backend "ebs-csi")}} + volumeBackend: {{ .Values.storage.backend }} + VolumeType: {{ .Values.storage.ebs.volumeType | default "gp3" }} + AvailabilityZone: {{ required ".Values.storage.ebs.availabilityZone is required" .Values.storage.ebs.availabilityZone }} + fsType: {{ .Values.storage.fsType | default "ext4" }} + encrypted: {{ .Values.storage.ebs.encrypted | default "false" | quote }} + {{- with .Values.storage.ebs.kmsKeyId }} + kmsKeyId: {{ . | quote }} + {{- end }} + {{- with .Values.storage.ebs.iops }} + iops: {{ . | quote }} + {{- end }} + {{- with .Values.storage.ebs.throughput }} + throughput: {{ . | quote }} + {{- end }} +{{- else if or (eq .Values.storage.backend "azuredisk") (eq .Values.storage.backend "azuredisk-csi")}} + volumeBackend: {{ .Values.storage.backend }} + kind: managed + skuName: {{ .Values.storage.azuredisk.skuName | default "Premium_LRS" }} + fsType: {{ .Values.storage.fsType | default "ext4" }} + cachingMode: {{ .Values.storage.azuredisk.cachingMode | default "None" }} + {{- with .Values.storage.azuredisk.availabilityZone }} + availabilityZone: {{ . | quote }} + {{- end }} + {{- with .Values.storage.azuredisk.resourceGroup }} + resourceGroup: {{ . | quote }} + {{- end }} +{{- end }} +{{- end -}} \ No newline at end of file diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/_helpers.tpl b/charts/codefresh/cf-runtime/6.4.1/templates/_helpers.tpl new file mode 100644 index 0000000000..72f44e36af --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/_helpers.tpl @@ -0,0 +1,51 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "cf-runtime.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 "cf-runtime.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 "cf-runtime.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "cf-runtime.labels" -}} +helm.sh/chart: {{ include "cf-runtime.chart" . }} +{{ include "cf-runtime.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "cf-runtime.selectorLabels" -}} +app.kubernetes.io/name: {{ include "cf-runtime.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/app-proxy/deployment.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/app-proxy/deployment.yaml new file mode 100644 index 0000000000..90341b3059 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/app-proxy/deployment.yaml @@ -0,0 +1,9 @@ +{{- $appProxyContext := deepCopy . }} +{{- $_ := set $appProxyContext "Values" (get .Values "appProxy") }} +{{- $_ := set $appProxyContext.Values "global" (get .Values "global") }} +{{- $_ := set $appProxyContext.Values "nameOverride" (get .Values "nameOverride") }} +{{- $_ := set $appProxyContext.Values "fullnameOverride" (get .Values "fullnameOverride") }} + +{{- if $appProxyContext.Values.enabled }} +{{- include "app-proxy.resources.deployment" $appProxyContext }} +{{- end }} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/app-proxy/ingress.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/app-proxy/ingress.yaml new file mode 100644 index 0000000000..56ab5e95ea --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/app-proxy/ingress.yaml @@ -0,0 +1,9 @@ +{{- $appProxyContext := deepCopy . }} +{{- $_ := set $appProxyContext "Values" (get .Values "appProxy") }} +{{- $_ := set $appProxyContext.Values "global" (get .Values "global") }} +{{- $_ := set $appProxyContext.Values "nameOverride" (get .Values "nameOverride") }} +{{- $_ := set $appProxyContext.Values "fullnameOverride" (get .Values "fullnameOverride") }} + +{{- if $appProxyContext.Values.enabled }} +{{- include "app-proxy.resources.ingress" $appProxyContext }} +{{- end }} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/app-proxy/rbac.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/app-proxy/rbac.yaml new file mode 100644 index 0000000000..4db87dcb45 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/app-proxy/rbac.yaml @@ -0,0 +1,9 @@ +{{- $appProxyContext := deepCopy . }} +{{- $_ := set $appProxyContext "Values" (get .Values "appProxy") }} +{{- $_ := set $appProxyContext.Values "global" (get .Values "global") }} +{{- $_ := set $appProxyContext.Values "nameOverride" (get .Values "nameOverride") }} +{{- $_ := set $appProxyContext.Values "fullnameOverride" (get .Values "fullnameOverride") }} + +{{- if $appProxyContext.Values.enabled }} +{{- include "app-proxy.resources.rbac" $appProxyContext }} +{{- end }} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/app-proxy/service.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/app-proxy/service.yaml new file mode 100644 index 0000000000..0b9d85ec0d --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/app-proxy/service.yaml @@ -0,0 +1,9 @@ +{{- $appProxyContext := deepCopy . }} +{{- $_ := set $appProxyContext "Values" (get .Values "appProxy") }} +{{- $_ := set $appProxyContext.Values "global" (get .Values "global") }} +{{- $_ := set $appProxyContext.Values "nameOverride" (get .Values "nameOverride") }} +{{- $_ := set $appProxyContext.Values "fullnameOverride" (get .Values "fullnameOverride") }} + +{{- if $appProxyContext.Values.enabled }} +{{- include "app-proxy.resources.service" $appProxyContext }} +{{- end }} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/event-exporter/deployment.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/event-exporter/deployment.yaml new file mode 100644 index 0000000000..4942882407 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/event-exporter/deployment.yaml @@ -0,0 +1,9 @@ +{{- $eventExporterContext := deepCopy . }} +{{- $_ := set $eventExporterContext "Values" (get .Values "event-exporter") }} +{{- $_ := set $eventExporterContext.Values "global" (get .Values "global") }} +{{- $_ := set $eventExporterContext.Values "nameOverride" (get .Values "nameOverride") }} +{{- $_ := set $eventExporterContext.Values "fullnameOverride" (get .Values "fullnameOverride") }} + +{{- if and $eventExporterContext.Values.enabled }} +{{- include "event-exporter.resources.deployment" $eventExporterContext }} +{{- end }} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/event-exporter/rbac.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/event-exporter/rbac.yaml new file mode 100644 index 0000000000..6a9bf5c65a --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/event-exporter/rbac.yaml @@ -0,0 +1,9 @@ +{{- $eventExporterContext := deepCopy . }} +{{- $_ := set $eventExporterContext "Values" (get .Values "event-exporter") }} +{{- $_ := set $eventExporterContext.Values "global" (get .Values "global") }} +{{- $_ := set $eventExporterContext.Values "nameOverride" (get .Values "nameOverride") }} +{{- $_ := set $eventExporterContext.Values "fullnameOverride" (get .Values "fullnameOverride") }} + +{{- if and $eventExporterContext.Values.enabled }} +{{- include "event-exporter.resources.rbac" $eventExporterContext }} +{{- end }} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/event-exporter/service.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/event-exporter/service.yaml new file mode 100644 index 0000000000..c5d856dfe3 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/event-exporter/service.yaml @@ -0,0 +1,11 @@ +{{- $eventExporterContext := deepCopy . }} +{{- $_ := set $eventExporterContext "Values" (get .Values "event-exporter") }} +{{- $_ := set $eventExporterContext.Values "global" (get .Values "global") }} +{{- $_ := set $eventExporterContext.Values "nameOverride" (get .Values "nameOverride") }} +{{- $_ := set $eventExporterContext.Values "fullnameOverride" (get .Values "fullnameOverride") }} + +{{- if $eventExporterContext.Values.enabled }} +{{- include "event-exporter.resources.service" $eventExporterContext }} +--- +{{- include "event-exporter.resources.serviceMonitor" $eventExporterContext }} +{{- end }} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/extra/extra-resources.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/extra/extra-resources.yaml new file mode 100644 index 0000000000..1a9777c649 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/extra/extra-resources.yaml @@ -0,0 +1,6 @@ +{{ $cfCommonTplSemver := printf "cf-common-%s" (index .Subcharts "cf-common").Chart.Version }} + +{{- range .Values.extraResources }} +--- +{{ include (printf "%s.tplrender" $cfCommonTplSemver) (dict "Values" . "context" $) }} +{{- end }} \ No newline at end of file diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/extra/runtime-images-cm.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/extra/runtime-images-cm.yaml new file mode 100644 index 0000000000..f269c84b2b --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/extra/runtime-images-cm.yaml @@ -0,0 +1,19 @@ +{{ $cfCommonTplSemver := printf "cf-common-%s" (index .Subcharts "cf-common").Chart.Version }} +{{ $values := .Values.runtime.engine.runtimeImages }} +--- +kind: ConfigMap +apiVersion: v1 +metadata: + {{- /* dummy template just to list runtime images */}} + name: {{ include "runtime.fullname" . }}-images + labels: + {{- include "runtime.labels" . | nindent 4 }} + annotations: + {{- with $values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +data: + images: | + {{- range $key, $val := $values }} + image: {{ $val }} + {{- end }} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/hooks/post-install/cm-update-runtime.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/hooks/post-install/cm-update-runtime.yaml new file mode 100644 index 0000000000..46a306c560 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/hooks/post-install/cm-update-runtime.yaml @@ -0,0 +1,18 @@ +{{ $cfCommonTplSemver := printf "cf-common-%s" (index .Subcharts "cf-common").Chart.Version }} +{{ $values := .Values.runtime.patch }} +{{- if $values.enabled }} +--- +kind: ConfigMap +apiVersion: v1 +metadata: + name: {{ include "runtime.fullname" . }}-spec + labels: + {{- include "runtime.labels" . | nindent 4 }} + annotations: + {{- with $values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +data: + runtime.yaml: | + {{ include "runtime.runtime-environment-spec.template" . | nindent 4 | trim }} +{{- end }} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/hooks/post-install/job-gencerts-dind.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/hooks/post-install/job-gencerts-dind.yaml new file mode 100644 index 0000000000..4a08a229c8 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/hooks/post-install/job-gencerts-dind.yaml @@ -0,0 +1,68 @@ +{{ $cfCommonTplSemver := printf "cf-common-%s" (index .Subcharts "cf-common").Chart.Version }} +{{ $values := .Values.runtime.gencerts }} +{{- if and $values.enabled }} +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "runtime.fullname" . }}-gencerts-dind + labels: + {{- include "runtime.labels" . | nindent 4 }} + annotations: + helm.sh/hook: post-install,post-upgrade + helm.sh/hook-weight: "3" + helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded + {{- with $values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- with $values.ttlSecondsAfterFinished }} + ttlSecondsAfterFinished: {{ . }} + {{- end }} + {{- with $values.backoffLimit }} + backoffLimit: {{ . | int }} + {{- end }} + template: + metadata: + name: {{ include "runtime.fullname" . }}-gencerts-dind + labels: + {{- include "runtime.labels" . | nindent 8 }} + spec: + {{- if $values.rbac.enabled }} + serviceAccountName: {{ template "runtime.fullname" . }}-gencerts-dind + {{- end }} + securityContext: + {{- toYaml $values.podSecurityContext | nindent 8 }} + containers: + - name: gencerts-dind + image: {{ include (printf "%s.image.name" $cfCommonTplSemver ) (dict "image" $values.image "context" .) }} + imagePullPolicy: {{ $values.image.pullPolicy | default "Always" }} + command: + - "/bin/bash" + args: + - -ec + - | {{ .Files.Get "files/configure-dind-certs.sh" | nindent 10 }} + env: + - name: NAMESPACE + value: {{ .Release.Namespace }} + - name: RELEASE + value: {{ .Release.Name }} + - name: CF_API_HOST + value: {{ include "runtime.runtime-environment-spec.codefresh-host" . }} + - name: CF_API_TOKEN + {{- include "runtime.installation-token-env-var-value" . | indent 10}} + {{- include (printf "%s.env-vars" $cfCommonTplSemver) (dict "Values" $values.env "context" .) | nindent 8 }} + {{- with $values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with $values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with $values.tolerations }} + tolerations: + {{- toYaml . | nindent 6 }} + {{- end }} + restartPolicy: OnFailure +{{- end }} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/hooks/post-install/job-update-runtime.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/hooks/post-install/job-update-runtime.yaml new file mode 100644 index 0000000000..955e882d77 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/hooks/post-install/job-update-runtime.yaml @@ -0,0 +1,77 @@ +{{ $cfCommonTplSemver := printf "cf-common-%s" (index .Subcharts "cf-common").Chart.Version }} +{{ $values := .Values.runtime.patch }} +{{- if $values.enabled }} +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "runtime.fullname" . }}-patch + labels: + {{- include "runtime.labels" . | nindent 4 }} + annotations: + helm.sh/hook: post-install,post-upgrade + helm.sh/hook-weight: "5" + helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded + {{- with $values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- with $values.ttlSecondsAfterFinished }} + ttlSecondsAfterFinished: {{ . }} + {{- end }} + {{- with $values.backoffLimit }} + backoffLimit: {{ . | int }} + {{- end }} + template: + metadata: + name: {{ include "runtime.fullname" . }}-patch + labels: + {{- include "runtime.labels" . | nindent 8 }} + spec: + securityContext: + {{- toYaml $values.podSecurityContext | nindent 8 }} + containers: + - name: patch-runtime + image: {{ include (printf "%s.image.name" $cfCommonTplSemver ) (dict "image" $values.image "context" .) }} + imagePullPolicy: {{ $values.image.pullPolicy | default "Always" }} + command: + - "/bin/bash" + args: + - -ec + - | + codefresh auth create-context --api-key $API_KEY --url $API_HOST + cat /usr/share/extras/runtime.yaml + codefresh get re +{{- if .Values.runtime.agent }} + codefresh patch re -f /usr/share/extras/runtime.yaml +{{- else }} + codefresh patch sys-re -f /usr/share/extras/runtime.yaml +{{- end }} + env: + - name: API_KEY + {{- include "runtime.installation-token-env-var-value" . | indent 10}} + - name: API_HOST + value: {{ include "runtime.runtime-environment-spec.codefresh-host" . }} + {{- include (printf "%s.env-vars" $cfCommonTplSemver) (dict "Values" $values.env "context" .) | nindent 8 }} + volumeMounts: + - name: config + mountPath: /usr/share/extras/runtime.yaml + subPath: runtime.yaml + {{- with $values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with $values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with $values.tolerations }} + tolerations: + {{- toYaml . | nindent 6 }} + {{- end }} + restartPolicy: OnFailure + volumes: + - name: config + configMap: + name: {{ include "runtime.fullname" . }}-spec +{{- end }} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/hooks/post-install/rbac-gencerts-dind.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/hooks/post-install/rbac-gencerts-dind.yaml new file mode 100644 index 0000000000..4907dac380 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/hooks/post-install/rbac-gencerts-dind.yaml @@ -0,0 +1,37 @@ +{{ $cfCommonTplSemver := printf "cf-common-%s" (index .Subcharts "cf-common").Chart.Version }} +{{ $values := .Values.runtime.gencerts }} +{{- if and $values.enabled }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "runtime.fullname" . }}-gencerts-dind + namespace: {{ .Release.Namespace }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ include "runtime.fullname" . }}-gencerts-dind + namespace: {{ .Release.Namespace }} +rules: + - apiGroups: + - "" + resources: + - secrets + - configmaps + verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "runtime.fullname" . }}-gencerts-dind + namespace: {{ .Release.Namespace }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ include "runtime.fullname" . }}-gencerts-dind +subjects: + - kind: ServiceAccount + name: {{ include "runtime.fullname" . }}-gencerts-dind + namespace: {{ .Release.Namespace }} +{{ end }} \ No newline at end of file diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/hooks/pre-delete/job-cleanup-resources.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/hooks/pre-delete/job-cleanup-resources.yaml new file mode 100644 index 0000000000..0e3c7659f1 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/hooks/pre-delete/job-cleanup-resources.yaml @@ -0,0 +1,73 @@ +{{ $cfCommonTplSemver := printf "cf-common-%s" (index .Subcharts "cf-common").Chart.Version }} +{{ $values := .Values.runtime.patch }} +{{- if and $values.enabled }} +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "runtime.fullname" . }}-cleanup + labels: + {{- include "runtime.labels" . | nindent 4 }} + annotations: + helm.sh/hook: pre-delete + helm.sh/hook-delete-policy: hook-succeeded,before-hook-creation + {{- with $values.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- with $values.ttlSecondsAfterFinished }} + ttlSecondsAfterFinished: {{ . }} + {{- end }} + {{- with $values.backoffLimit }} + backoffLimit: {{ . | int }} + {{- end }} + template: + metadata: + name: {{ include "runtime.fullname" . }}-cleanup + labels: + {{- include "runtime.labels" . | nindent 8 }} + spec: + {{- if $values.rbac.enabled }} + serviceAccountName: {{ template "runtime.fullname" . }}-cleanup + {{- end }} + securityContext: + {{- toYaml $values.podSecurityContext | nindent 8 }} + containers: + - name: cleanup + image: {{ include (printf "%s.image.name" $cfCommonTplSemver ) (dict "image" $values.image "context" .) }} + imagePullPolicy: {{ $values.image.pullPolicy | default "Always" }} + command: + - "/bin/bash" + args: + - -ec + - | {{ .Files.Get "files/cleanup-runtime.sh" | nindent 10 }} + env: + - name: AGENT_NAME + value: {{ include "runtime.runtime-environment-spec.agent-name" . }} + - name: RUNTIME_NAME + value: {{ include "runtime.runtime-environment-spec.runtime-name" . }} + - name: API_HOST + value: {{ include "runtime.runtime-environment-spec.codefresh-host" . }} + - name: API_TOKEN + {{- include "runtime.installation-token-env-var-value" . | indent 10}} + - name: AGENT + value: {{ .Values.runtime.agent | quote }} + - name: AGENT_SECRET_NAME + value: {{ include "runner.fullname" . }} + - name: DIND_SECRET_NAME + value: codefresh-certs-server + {{- include (printf "%s.env-vars" $cfCommonTplSemver) (dict "Values" $values.env "context" .) | nindent 8 }} + {{- with $values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with $values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with $values.tolerations }} + tolerations: + {{- toYaml . | nindent 6 }} + {{- end }} + restartPolicy: OnFailure +{{- end }} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/hooks/pre-delete/rbac-cleanup-resources.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/hooks/pre-delete/rbac-cleanup-resources.yaml new file mode 100644 index 0000000000..468ec2212d --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/hooks/pre-delete/rbac-cleanup-resources.yaml @@ -0,0 +1,46 @@ +{{ $cfCommonTplSemver := printf "cf-common-%s" (index .Subcharts "cf-common").Chart.Version }} +{{ $values := .Values.runtime.patch }} +{{- if and $values.enabled }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "runtime.fullname" . }}-cleanup + namespace: {{ .Release.Namespace }} + annotations: + "helm.sh/hook": pre-delete + "helm.sh/hook-delete-policy": hook-succeeded,before-hook-creation,hook-failed +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ include "runtime.fullname" . }}-cleanup + namespace: {{ .Release.Namespace }} + annotations: + "helm.sh/hook": pre-delete + "helm.sh/hook-delete-policy": hook-succeeded,before-hook-creation,hook-failed +rules: + - apiGroups: + - "*" + resources: + - "*" + verbs: + - "*" +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "runtime.fullname" . }}-cleanup + namespace: {{ .Release.Namespace }} + annotations: + "helm.sh/hook": pre-delete + "helm.sh/hook-delete-policy": hook-succeeded,before-hook-creation,hook-failed +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ include "runtime.fullname" . }}-cleanup +subjects: + - kind: ServiceAccount + name: {{ include "runtime.fullname" . }}-cleanup + namespace: {{ .Release.Namespace }} +{{ end }} \ No newline at end of file diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/monitor/deployment.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/monitor/deployment.yaml new file mode 100644 index 0000000000..00c9fb2f91 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/monitor/deployment.yaml @@ -0,0 +1,9 @@ +{{- $monitorContext := deepCopy . }} +{{- $_ := set $monitorContext "Values" (get .Values "monitor") }} +{{- $_ := set $monitorContext.Values "global" (get .Values "global") }} +{{- $_ := set $monitorContext.Values "nameOverride" (get .Values "nameOverride") }} +{{- $_ := set $monitorContext.Values "fullnameOverride" (get .Values "fullnameOverride") }} + +{{- if $monitorContext.Values.enabled }} +{{- include "monitor.resources.deployment" $monitorContext }} +{{- end }} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/monitor/rbac.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/monitor/rbac.yaml new file mode 100644 index 0000000000..f9812d565d --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/monitor/rbac.yaml @@ -0,0 +1,9 @@ +{{- $monitorContext := deepCopy . }} +{{- $_ := set $monitorContext "Values" (get .Values "monitor") }} +{{- $_ := set $monitorContext.Values "global" (get .Values "global") }} +{{- $_ := set $monitorContext.Values "nameOverride" (get .Values "nameOverride") }} +{{- $_ := set $monitorContext.Values "fullnameOverride" (get .Values "fullnameOverride") }} + +{{- if $monitorContext.Values.enabled }} +{{- include "monitor.resources.rbac" $monitorContext }} +{{- end }} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/monitor/service.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/monitor/service.yaml new file mode 100644 index 0000000000..f99706614a --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/monitor/service.yaml @@ -0,0 +1,9 @@ +{{- $monitorContext := deepCopy . }} +{{- $_ := set $monitorContext "Values" (get .Values "monitor") }} +{{- $_ := set $monitorContext.Values "global" (get .Values "global") }} +{{- $_ := set $monitorContext.Values "nameOverride" (get .Values "nameOverride") }} +{{- $_ := set $monitorContext.Values "fullnameOverride" (get .Values "fullnameOverride") }} + +{{- if $monitorContext.Values.enabled }} +{{- include "monitor.resources.service" $monitorContext }} +{{- end }} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/other/external-secrets.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/other/external-secrets.yaml new file mode 100644 index 0000000000..dc24e24e51 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/other/external-secrets.yaml @@ -0,0 +1,2 @@ +{{ $templateName := printf "cf-common-%s.external-secrets" (index .Subcharts "cf-common").Chart.Version }} +{{- include $templateName . -}} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/other/podMonitor.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/other/podMonitor.yaml new file mode 100644 index 0000000000..4319b722b9 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/other/podMonitor.yaml @@ -0,0 +1,2 @@ +{{ $templateName := printf "cf-common-%s.podMonitor" (index .Subcharts "cf-common").Chart.Version }} +{{- include $templateName . -}} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/other/serviceMonitor.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/other/serviceMonitor.yaml new file mode 100644 index 0000000000..29f890fe2b --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/other/serviceMonitor.yaml @@ -0,0 +1,2 @@ +{{ $templateName := printf "cf-common-%s.serviceMonitor" (index .Subcharts "cf-common").Chart.Version }} +{{- include $templateName . -}} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/runner/deployment.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/runner/deployment.yaml new file mode 100644 index 0000000000..85777c487f --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/runner/deployment.yaml @@ -0,0 +1,9 @@ +{{- $runnerContext := deepCopy . }} +{{- $_ := set $runnerContext "Values" (get .Values "runner") }} +{{- $_ := set $runnerContext.Values "global" (get .Values "global") }} +{{- $_ := set $runnerContext.Values "nameOverride" (get .Values "nameOverride") }} +{{- $_ := set $runnerContext.Values "fullnameOverride" (get .Values "fullnameOverride") }} + +{{- if and $runnerContext.Values.enabled .Values.runtime.agent }} +{{- include "runner.resources.deployment" $runnerContext }} +{{- end }} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/runner/rbac.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/runner/rbac.yaml new file mode 100644 index 0000000000..d5f8c13233 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/runner/rbac.yaml @@ -0,0 +1,9 @@ +{{- $runnerContext := deepCopy . }} +{{- $_ := set $runnerContext "Values" (get .Values "runner") }} +{{- $_ := set $runnerContext.Values "global" (get .Values "global") }} +{{- $_ := set $runnerContext.Values "nameOverride" (get .Values "nameOverride") }} +{{- $_ := set $runnerContext.Values "fullnameOverride" (get .Values "fullnameOverride") }} + +{{- if and $runnerContext.Values.enabled .Values.runtime.agent }} +{{- include "runner.resources.rbac" $runnerContext }} +{{- end }} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/runtime/_helpers.tpl b/charts/codefresh/cf-runtime/6.4.1/templates/runtime/_helpers.tpl new file mode 100644 index 0000000000..6ba04fcc3e --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/runtime/_helpers.tpl @@ -0,0 +1,123 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "runtime.name" -}} + {{- printf "%s" (include "cf-runtime.name" .) | 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 "runtime.fullname" -}} + {{- printf "%s" (include "cf-runtime.fullname" .) | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "runtime.labels" -}} +{{ include "cf-runtime.labels" . }} +codefresh.io/application: runtime +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "runtime.selectorLabels" -}} +{{ include "cf-runtime.selectorLabels" . }} +codefresh.io/application: runtime +{{- end }} + +{{/* +Return runtime image (classic runtime) with private registry prefix +*/}} +{{- define "runtime.runtimeImageName" -}} + {{- if .registry -}} + {{- $imageName := (trimPrefix "quay.io/" .imageFullName) -}} + {{- printf "%s/%s" .registry $imageName -}} + {{- else -}} + {{- printf "%s" .imageFullName -}} + {{- end -}} +{{- end -}} + +{{/* +Environment variable value of Codefresh installation token +*/}} +{{- define "runtime.installation-token-env-var-value" -}} + {{- if .Values.global.codefreshToken }} +valueFrom: + secretKeyRef: + name: {{ include "runtime.installation-token-secret-name" . }} + key: codefresh-api-token + {{- else if .Values.global.codefreshTokenSecretKeyRef }} +valueFrom: + secretKeyRef: + {{- .Values.global.codefreshTokenSecretKeyRef | toYaml | nindent 4 }} + {{- end }} +{{- end }} + +{{/* +Environment variable value of Codefresh agent token +*/}} +{{- define "runtime.agent-token-env-var-value" -}} + {{- if .Values.global.agentToken }} +{{- printf "%s" .Values.global.agentToken | toYaml }} + {{- else if .Values.global.agentTokenSecretKeyRef }} +valueFrom: + secretKeyRef: + {{- .Values.global.agentTokenSecretKeyRef | toYaml | nindent 4 }} + {{- end }} +{{- end }} + +{{/* +Print Codefresh API token secret name +*/}} +{{- define "runtime.installation-token-secret-name" }} +{{- print "codefresh-user-token" }} +{{- end }} + +{{/* +Print Codefresh host +*/}} +{{- define "runtime.runtime-environment-spec.codefresh-host" }} +{{- if and (not .Values.global.codefreshHost) }} + {{- fail "ERROR: .global.codefreshHost is required" }} +{{- else }} + {{- printf "%s" (trimSuffix "/" .Values.global.codefreshHost) }} +{{- end }} +{{- end }} + +{{/* +Print runtime-environment name +*/}} +{{- define "runtime.runtime-environment-spec.runtime-name" }} +{{- if and (not .Values.global.runtimeName) }} + {{- printf "%s/%s" .Values.global.context .Release.Namespace }} +{{- else }} + {{- printf "%s" .Values.global.runtimeName }} +{{- end }} +{{- end }} + +{{/* +Print agent name +*/}} +{{- define "runtime.runtime-environment-spec.agent-name" }} +{{- if and (not .Values.global.agentName) }} + {{- printf "%s_%s" .Values.global.context .Release.Namespace }} +{{- else }} + {{- printf "%s" .Values.global.agentName }} +{{- end }} +{{- end }} + +{{/* +Print context +*/}} +{{- define "runtime.runtime-environment-spec.context-name" }} +{{- if and (not .Values.global.context) }} + {{- fail "ERROR: .global.context is required" }} +{{- else }} + {{- printf "%s" .Values.global.context }} +{{- end }} +{{- end }} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/runtime/cm-dind-daemon.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/runtime/cm-dind-daemon.yaml new file mode 100644 index 0000000000..fc7f92905b --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/runtime/cm-dind-daemon.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + {{- /* has to be a constant */}} + name: codefresh-dind-config + labels: + {{- include "runtime.labels" . | nindent 4 }} +data: + daemon.json: | +{{ coalesce .Values.re.dindDaemon .Values.runtime.dindDaemon | toPrettyJson | indent 4 }} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/runtime/rbac.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/runtime/rbac.yaml new file mode 100644 index 0000000000..a51b125262 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/runtime/rbac.yaml @@ -0,0 +1,48 @@ +{{ $values := .Values.runtime }} +--- +{{- if or $values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + {{- /* has to be a constant */}} + name: codefresh-engine + labels: + {{- include "runtime.labels" . | nindent 4 }} + {{- with $values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} +--- +{{- if $values.rbac.create }} +kind: Role +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: codefresh-engine + labels: + {{- include "runner.labels" . | nindent 4 }} +rules: + - apiGroups: [ "" ] + resources: [ "secrets" ] + verbs: [ "get" ] +{{- with $values.rbac.rules }} + {{ toYaml . | nindent 2 }} +{{- end }} +{{- end }} +--- +{{- if and $values.serviceAccount.create $values.rbac.create }} +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: codefresh-engine + labels: + {{- include "runner.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: codefresh-engine +roleRef: + kind: Role + name: codefresh-engine + apiGroup: rbac.authorization.k8s.io +{{- end }} + diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/runtime/runtime-env-spec-tmpl.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/runtime/runtime-env-spec-tmpl.yaml new file mode 100644 index 0000000000..baf7265116 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/runtime/runtime-env-spec-tmpl.yaml @@ -0,0 +1,214 @@ +{{- define "runtime.runtime-environment-spec.template" }} +{{- $cfCommonTplSemver := printf "cf-common-%s" (index .Subcharts "cf-common").Chart.Version -}} +{{- $kubeconfigFilePath := (include "runtime.runtime-environment-spec.runtime-name" .) -}} +{{- $name := (include "runtime.runtime-environment-spec.runtime-name" .) -}} +{{- $engineContext := .Values.runtime.engine -}} +{{- $dindContext := .Values.runtime.dind -}} +{{- $imageRegistry := .Values.global.imageRegistry -}} +metadata: + name: {{ include "runtime.runtime-environment-spec.runtime-name" . }} + agent: {{ .Values.runtime.agent }} +runtimeScheduler: + type: KubernetesPod + {{- if $engineContext.image }} + image: {{ include (printf "%s.image.name" $cfCommonTplSemver ) (dict "image" $engineContext.image "context" .) | squote }} + {{- end }} + imagePullPolicy: {{ $engineContext.image.pullPolicy }} + {{- with $engineContext.command }} + command: {{- toYaml . | nindent 4 }} + {{- end }} + envVars: + {{- with $engineContext.env }} + {{- range $key, $val := . }} + {{- if or (kindIs "bool" $val) (kindIs "int" $val) (kindIs "float64" $val) }} + {{ $key }}: {{ $val | squote }} + {{- else }} + {{ $key }}: {{ $val }} + {{- end }} + {{- end }} + {{- end }} + COMPOSE_IMAGE: {{ include "runtime.runtimeImageName" (dict "registry" $imageRegistry "imageFullName" $engineContext.runtimeImages.COMPOSE_IMAGE) | squote }} + CONTAINER_LOGGER_IMAGE: {{ include "runtime.runtimeImageName" (dict "registry" $imageRegistry "imageFullName" $engineContext.runtimeImages.CONTAINER_LOGGER_IMAGE) | squote }} + DOCKER_BUILDER_IMAGE: {{ include "runtime.runtimeImageName" (dict "registry" $imageRegistry "imageFullName" $engineContext.runtimeImages.DOCKER_BUILDER_IMAGE) | squote }} + DOCKER_PULLER_IMAGE: {{ include "runtime.runtimeImageName" (dict "registry" $imageRegistry "imageFullName" $engineContext.runtimeImages.DOCKER_PULLER_IMAGE) | squote }} + DOCKER_PUSHER_IMAGE: {{ include "runtime.runtimeImageName" (dict "registry" $imageRegistry "imageFullName" $engineContext.runtimeImages.DOCKER_PUSHER_IMAGE) | squote }} + DOCKER_TAG_PUSHER_IMAGE: {{ include "runtime.runtimeImageName" (dict "registry" $imageRegistry "imageFullName" $engineContext.runtimeImages.DOCKER_TAG_PUSHER_IMAGE) | squote }} + FS_OPS_IMAGE: {{ include "runtime.runtimeImageName" (dict "registry" $imageRegistry "imageFullName" $engineContext.runtimeImages.FS_OPS_IMAGE) | squote }} + GIT_CLONE_IMAGE: {{ include "runtime.runtimeImageName" (dict "registry" $imageRegistry "imageFullName" $engineContext.runtimeImages.GIT_CLONE_IMAGE) | squote }} + KUBE_DEPLOY: {{ include "runtime.runtimeImageName" (dict "registry" $imageRegistry "imageFullName" $engineContext.runtimeImages.KUBE_DEPLOY) | squote }} + PIPELINE_DEBUGGER_IMAGE: {{ include "runtime.runtimeImageName" (dict "registry" $imageRegistry "imageFullName" $engineContext.runtimeImages.PIPELINE_DEBUGGER_IMAGE) | squote }} + TEMPLATE_ENGINE: {{ include "runtime.runtimeImageName" (dict "registry" $imageRegistry "imageFullName" $engineContext.runtimeImages.TEMPLATE_ENGINE) | squote }} + CR_6177_FIXER: {{ include "runtime.runtimeImageName" (dict "registry" $imageRegistry "imageFullName" $engineContext.runtimeImages.CR_6177_FIXER) | squote }} + GC_BUILDER_IMAGE: {{ include "runtime.runtimeImageName" (dict "registry" $imageRegistry "imageFullName" $engineContext.runtimeImages.GC_BUILDER_IMAGE) | squote }} + COSIGN_IMAGE_SIGNER_IMAGE: {{ include "runtime.runtimeImageName" (dict "registry" $imageRegistry "imageFullName" $engineContext.runtimeImages.COSIGN_IMAGE_SIGNER_IMAGE) | squote }} + {{- with $engineContext.userEnvVars }} + userEnvVars: {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $engineContext.workflowLimits }} + workflowLimits: {{- toYaml . | nindent 4 }} + {{- end }} + cluster: + namespace: {{ .Release.Namespace }} + serviceAccount: {{ $engineContext.serviceAccount }} + {{- if .Values.runtime.agent }} + clusterProvider: + accountId: {{ .Values.global.accountId }} + selector: {{ include "runtime.runtime-environment-spec.context-name" . }} + {{- else }} + {{- if .Values.runtime.inCluster }} + inCluster: true + kubeconfigFilePath: null + {{- else }} + name: {{ $name }} + kubeconfigFilePath: {{ printf "/etc/kubeconfig/%s" $kubeconfigFilePath }} + {{- end }} + {{- end }} + {{- with $engineContext.nodeSelector }} + nodeSelector: {{- toYaml . | nindent 6 }} + {{- end }} + {{- with $engineContext.affinity }} + affinity: {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $engineContext.tolerations }} + tolerations: {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $engineContext.podAnnotations }} + annotations: + {{- range $key, $val := . }} + {{ $key }}: {{ $val | squote }} + {{- end }} + {{- end }} + {{- with $engineContext.podLabels }} + labels: {{- toYaml . | nindent 4 }} + {{- end }} + {{- if $engineContext.schedulerName }} + schedulerName: {{ $engineContext.schedulerName }} + {{- end }} + resources: + {{- if $engineContext.resources}} + {{- toYaml $engineContext.resources | nindent 4 }} + {{- end }} + {{- with $engineContext.terminationGracePeriodSeconds }} + terminationGracePeriodSeconds: {{ . }} + {{- end }} +dockerDaemonScheduler: + type: DindKubernetesPod + {{- if $dindContext.image }} + dindImage: {{ include (printf "%s.image.name" $cfCommonTplSemver ) (dict "image" $dindContext.image "context" .) | squote }} + {{- end }} + imagePullPolicy: {{ $dindContext.image.pullPolicy }} + {{- with $dindContext.userAccess }} + userAccess: {{ . }} + {{- end }} + {{- with $dindContext.env }} + envVars: + {{- range $key, $val := . }} + {{- if or (kindIs "bool" $val) (kindIs "int" $val) (kindIs "float64" $val) }} + {{ $key }}: {{ $val | squote }} + {{- else }} + {{ $key }}: {{ $val }} + {{- end }} + {{- end }} + {{- end }} + cluster: + namespace: {{ .Release.Namespace }} + serviceAccount: {{ $dindContext.serviceAccount }} + {{- if .Values.runtime.agent }} + clusterProvider: + accountId: {{ .Values.global.accountId }} + selector: {{ include "runtime.runtime-environment-spec.context-name" . }} + {{- else }} + {{- if .Values.runtime.inCluster }} + inCluster: true + kubeconfigFilePath: null + {{- else }} + name: {{ $name }} + kubeconfigFilePath: {{ printf "/etc/kubeconfig/%s" $kubeconfigFilePath }} + {{- end }} + {{- end }} + {{- with $dindContext.nodeSelector }} + nodeSelector: {{- toYaml . | nindent 6 }} + {{- end }} + {{- with $dindContext.affinity }} + affinity: {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $dindContext.tolerations }} + tolerations: {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $dindContext.podAnnotations }} + annotations: + {{- range $key, $val := . }} + {{ $key }}: {{ $val | squote }} + {{- end }} + {{- end }} + {{- with $dindContext.podLabels }} + labels: {{- toYaml . | nindent 4 }} + {{- end }} + {{- if $dindContext.schedulerName }} + schedulerName: {{ $dindContext.schedulerName }} + {{- end }} + {{- if $dindContext.pvcs }} + pvcs: + {{- range $index, $pvc := $dindContext.pvcs }} + - name: {{ $pvc.name }} + reuseVolumeSelector: {{ $pvc.reuseVolumeSelector | squote }} + reuseVolumeSortOrder: {{ $pvc.reuseVolumeSortOrder }} + storageClassName: {{ include (printf "%v.tplrender" $cfCommonTplSemver) (dict "Values" $pvc.storageClassName "context" $) }} + volumeSize: {{ $pvc.volumeSize }} + {{- with $pvc.annotations }} + annotations: {{ . | toYaml | nindent 8 }} + {{- end }} + {{- end }} + {{- end }} + defaultDindResources: + {{- with $dindContext.resources }} + {{- if not .requests }} + limits: {{- toYaml .limits | nindent 6 }} + requests: null + {{- else }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} + {{- with $dindContext.terminationGracePeriodSeconds }} + terminationGracePeriodSeconds: {{ . }} + {{- end }} + {{- with $dindContext.userVolumeMounts }} + userVolumeMounts: {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $dindContext.userVolumes }} + userVolumes: {{- toYaml . | nindent 4 }} + {{- end }} + {{- if and (not .Values.runtime.agent) }} + clientCertPath: /etc/ssl/cf/ + volumeMounts: + codefresh-certs-server: + name: codefresh-certs-server + mountPath: /etc/ssl/cf + readOnly: false + volumes: + codefresh-certs-server: + name: codefresh-certs-server + secret: + secretName: codefresh-certs-server + {{- end }} +extends: {{- toYaml .Values.runtime.runtimeExtends | nindent 2 }} + {{- if .Values.runtime.description }} +description: {{ .Values.runtime.description }} + {{- else }} +description: null + {{- end }} +{{- if .Values.global.accountId }} +accountId: {{ .Values.global.accountId }} +{{- end }} +{{- if not .Values.runtime.agent }} +accounts: {{- toYaml .Values.runtime.accounts | nindent 2 }} +{{- end }} +{{- if .Values.appProxy.enabled }} +appProxy: + externalIP: >- + {{ printf "https://%s%s" .Values.appProxy.ingress.host (.Values.appProxy.ingress.pathPrefix | default "/") }} +{{- end }} +{{- if not .Values.runtime.agent }} +systemHybrid: true +{{- end }} +{{- end }} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/runtime/secret.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/runtime/secret.yaml new file mode 100644 index 0000000000..2366d3ccf6 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/runtime/secret.yaml @@ -0,0 +1,11 @@ +{{- if and .Values.global.codefreshToken }} +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + name: {{ include "runtime.installation-token-secret-name" . }} + labels: + {{- include "runtime.labels" . | nindent 4 }} +stringData: + codefresh-api-token: {{ .Values.global.codefreshToken }} +{{- end }} \ No newline at end of file diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/runtime/svc-dind.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/runtime/svc-dind.yaml new file mode 100644 index 0000000000..098edb4e87 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/runtime/svc-dind.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + {{- include "runtime.labels" . | nindent 4 }} + app: dind + {{/* has to be a constant */}} + name: dind +spec: + ports: + - name: "dind-port" + port: 1300 + protocol: TCP + clusterIP: None + selector: + app: dind diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/volume-provisioner/cronjob.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/volume-provisioner/cronjob.yaml new file mode 100644 index 0000000000..db955bc771 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/volume-provisioner/cronjob.yaml @@ -0,0 +1,11 @@ +{{- $volumeProvisionerContext := deepCopy . }} +{{- $_ := set $volumeProvisionerContext "Values" (get .Values.volumeProvisioner "dind-volume-cleanup") }} +{{- $_ := set $volumeProvisionerContext.Values "serviceAccount" (get .Values.volumeProvisioner "serviceAccount") }} +{{- $_ := set $volumeProvisionerContext.Values "global" (get .Values "global") }} +{{- $_ := set $volumeProvisionerContext.Values "storage" (get .Values "storage") }} +{{- $_ := set $volumeProvisionerContext.Values "nameOverride" (get .Values "nameOverride") }} +{{- $_ := set $volumeProvisionerContext.Values "fullnameOverride" (get .Values "fullnameOverride") }} + +{{- if and $volumeProvisionerContext.Values.enabled .Values.volumeProvisioner.enabled }} +{{- include "dind-volume-provisioner.resources.cronjob" $volumeProvisionerContext }} +{{- end }} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/volume-provisioner/daemonset.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/volume-provisioner/daemonset.yaml new file mode 100644 index 0000000000..39927149e8 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/volume-provisioner/daemonset.yaml @@ -0,0 +1,11 @@ +{{- $volumeProvisionerContext := deepCopy . }} +{{- $_ := set $volumeProvisionerContext "Values" (get .Values.volumeProvisioner "dind-lv-monitor") }} +{{- $_ := set $volumeProvisionerContext.Values "serviceAccount" (get .Values.volumeProvisioner "serviceAccount") }} +{{- $_ := set $volumeProvisionerContext.Values "global" (get .Values "global") }} +{{- $_ := set $volumeProvisionerContext.Values "storage" (get .Values "storage") }} +{{- $_ := set $volumeProvisionerContext.Values "nameOverride" (get .Values "nameOverride") }} +{{- $_ := set $volumeProvisionerContext.Values "fullnameOverride" (get .Values "fullnameOverride") }} + +{{- if and $volumeProvisionerContext.Values.enabled .Values.volumeProvisioner.enabled }} +{{- include "dind-volume-provisioner.resources.daemonset" $volumeProvisionerContext }} +{{- end }} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/volume-provisioner/deployment.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/volume-provisioner/deployment.yaml new file mode 100644 index 0000000000..522fa8791f --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/volume-provisioner/deployment.yaml @@ -0,0 +1,10 @@ +{{- $volumeProvisionerContext := deepCopy . }} +{{- $_ := set $volumeProvisionerContext "Values" (get .Values "volumeProvisioner") }} +{{- $_ := set $volumeProvisionerContext.Values "global" (get .Values "global") }} +{{- $_ := set $volumeProvisionerContext.Values "storage" (get .Values "storage") }} +{{- $_ := set $volumeProvisionerContext.Values "nameOverride" (get .Values "nameOverride") }} +{{- $_ := set $volumeProvisionerContext.Values "fullnameOverride" (get .Values "fullnameOverride") }} + +{{- if $volumeProvisionerContext.Values.enabled }} +{{- include "dind-volume-provisioner.resources.deployment" $volumeProvisionerContext }} +{{- end }} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/volume-provisioner/rbac.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/volume-provisioner/rbac.yaml new file mode 100644 index 0000000000..f3ae9609f9 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/volume-provisioner/rbac.yaml @@ -0,0 +1,9 @@ +{{- $volumeProvisionerContext := deepCopy . }} +{{- $_ := set $volumeProvisionerContext "Values" (get .Values "volumeProvisioner") }} +{{- $_ := set $volumeProvisionerContext.Values "global" (get .Values "global") }} +{{- $_ := set $volumeProvisionerContext.Values "nameOverride" (get .Values "nameOverride") }} +{{- $_ := set $volumeProvisionerContext.Values "fullnameOverride" (get .Values "fullnameOverride") }} + +{{- if $volumeProvisionerContext.Values.enabled }} +{{- include "dind-volume-provisioner.resources.rbac" $volumeProvisionerContext }} +{{- end }} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/volume-provisioner/secret.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/volume-provisioner/secret.yaml new file mode 100644 index 0000000000..accf601d13 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/volume-provisioner/secret.yaml @@ -0,0 +1,10 @@ +{{- $volumeProvisionerContext := deepCopy . }} +{{- $_ := set $volumeProvisionerContext "Values" (get .Values "volumeProvisioner") }} +{{- $_ := set $volumeProvisionerContext.Values "global" (get .Values "global") }} +{{- $_ := set $volumeProvisionerContext.Values "storage" (get .Values "storage") }} +{{- $_ := set $volumeProvisionerContext.Values "nameOverride" (get .Values "nameOverride") }} +{{- $_ := set $volumeProvisionerContext.Values "fullnameOverride" (get .Values "fullnameOverride") }} + +{{- if $volumeProvisionerContext.Values.enabled }} +{{- include "dind-volume-provisioner.resources.secret" $volumeProvisionerContext }} +{{- end }} diff --git a/charts/codefresh/cf-runtime/6.4.1/templates/volume-provisioner/storageclass.yaml b/charts/codefresh/cf-runtime/6.4.1/templates/volume-provisioner/storageclass.yaml new file mode 100644 index 0000000000..77a7602da1 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/templates/volume-provisioner/storageclass.yaml @@ -0,0 +1,10 @@ +{{- $volumeProvisionerContext := deepCopy . }} +{{- $_ := set $volumeProvisionerContext "Values" (get .Values "volumeProvisioner") }} +{{- $_ := set $volumeProvisionerContext.Values "global" (get .Values "global") }} +{{- $_ := set $volumeProvisionerContext.Values "storage" (get .Values "storage") }} +{{- $_ := set $volumeProvisionerContext.Values "nameOverride" (get .Values "nameOverride") }} +{{- $_ := set $volumeProvisionerContext.Values "fullnameOverride" (get .Values "fullnameOverride") }} + +{{- if $volumeProvisionerContext.Values.enabled }} +{{- include "dind-volume-provisioner.resources.storageclass" $volumeProvisionerContext }} +{{- end }} diff --git a/charts/codefresh/cf-runtime/6.4.1/values.yaml b/charts/codefresh/cf-runtime/6.4.1/values.yaml new file mode 100644 index 0000000000..c501339551 --- /dev/null +++ b/charts/codefresh/cf-runtime/6.4.1/values.yaml @@ -0,0 +1,951 @@ +# -- String to partially override cf-runtime.fullname template (will maintain the release name) +nameOverride: "" +# -- String to fully override cf-runtime.fullname template +fullnameOverride: "" + +# -- Global parameters +# @default -- See below +global: + # -- Global Docker image registry + imageRegistry: "" + # -- Global Docker registry secret names as array + imagePullSecrets: [] + + # -- URL of Codefresh Platform (required!) + codefreshHost: "https://g.codefresh.io" + # -- User token in plain text (required if `global.codefreshTokenSecretKeyRef` is omitted!) + # Ref: https://g.codefresh.io/user/settings (see API Keys) + # Minimal API key scopes: Runner-Installation(read+write), Agent(read+write), Agents(read+write) + codefreshToken: "" + # -- User token that references an existing secret containing API key (required if `global.codefreshToken` is omitted!) + codefreshTokenSecretKeyRef: {} + + # E.g. + # codefreshTokenSecretKeyRef: + # name: my-codefresh-api-token + # key: codefresh-api-token + + # -- Account ID (required!) + # Can be obtained here https://g.codefresh.io/2.0/account-settings/account-information + accountId: "" + + # -- K8s context name (required!) + context: "" + # E.g. + # context: prod-ue1-runtime-1 + + # -- Agent Name (optional!) + # If omitted, the following format will be used `{{ .Values.global.context }}_{{ .Release.Namespace }}` + agentName: "" + # E.g. + # agentName: prod-ue1-runtime-1 + + # -- Runtime name (optional!) + # If omitted, the following format will be used `{{ .Values.global.context }}/{{ .Release.Namespace }}` + runtimeName: "" + # E.g. + # runtimeName: prod-ue1-runtime-1/namespace + + # -- DEPRECATED Agent token in plain text. + # !!! MUST BE provided if migrating from < 6.x chart version + agentToken: "" + # -- DEPRECATED Agent token that references an existing secret containing API key. + # !!! MUST BE provided if migrating from < 6.x chart version + agentTokenSecretKeyRef: {} + # E.g. + # agentTokenSecretKeyRef: + # name: my-codefresh-agent-secret + # key: codefresh-agent-token + +# DEPRECATED -- Use `.Values.global.imageRegistry` instead +dockerRegistry: "" + +# DEPRECATED -- Use `.Values.runtime` instead +re: {} + +# -- Runner parameters +# @default -- See below +runner: + # -- Enable the runner + enabled: true + # -- Set number of pods + replicasCount: 1 + # -- Upgrade strategy + updateStrategy: + type: RollingUpdate + # -- Set pod annotations + podAnnotations: {} + + # -- Set image + image: + registry: quay.io + repository: codefresh/venona + tag: 1.10.2 + + # -- Init container + init: + image: + registry: quay.io + repository: codefresh/cli + tag: 0.85.0-rootless + + resources: + limits: + memory: 512Mi + cpu: '1' + requests: + memory: 256Mi + cpu: '0.2' + + # -- Sidecar container + # Reconciles runtime spec from Codefresh API for drift detection + sidecar: + enabled: false + image: + registry: quay.io + repository: codefresh/codefresh-shell + tag: 0.0.2 + env: + RECONCILE_INTERVAL: 300 + resources: {} + + # -- Add additional env vars + env: {} + # E.g. + # env: + # WORKFLOW_CONCURRENCY: 50 # The number of workflow creation and termination tasks the Runner can handle in parallel. Defaults to 50 + + # -- Service Account parameters + serviceAccount: + # -- Create service account + create: true + # -- Override service account name + name: "" + # -- Additional service account annotations + annotations: {} + + # -- RBAC parameters + rbac: + # -- Create RBAC resources + create: true + # -- Add custom rule to the role + rules: [] + + # -- Set security context for the pod + # @default -- See below + podSecurityContext: + enabled: true + runAsUser: 10001 + runAsGroup: 10001 + fsGroup: 10001 + + # -- Readiness probe configuration + # @default -- See below + readinessProbe: + failureThreshold: 5 + initialDelaySeconds: 5 + periodSeconds: 5 + successThreshold: 1 + timeoutSeconds: 5 + + # -- Set requests and limits + resources: {} + # -- Set node selector + nodeSelector: {} + # -- Set tolerations + tolerations: [] + # -- Set affinity + affinity: {} + +# -- Volume Provisioner parameters +# @default -- See below +volumeProvisioner: + # -- Enable volume-provisioner + enabled: true + # -- Set number of pods + replicasCount: 1 + # -- Upgrade strategy + updateStrategy: + type: Recreate + # -- Set pod annotations + podAnnotations: {} + + # -- Set image + image: + registry: quay.io + repository: codefresh/dind-volume-provisioner + tag: 1.35.0 + # -- Add additional env vars + env: {} + # E.g. + # env: + # THREADINESS: 4 # The number of PVC requests the dind-volume-provisioner can process in parallel. Defaults to 4 + + # -- Service Account parameters + serviceAccount: + # -- Create service account + create: true + # -- Override service account name + name: "" + # -- Additional service account annotations + annotations: {} + # E.g. + # serviceAccount: + # annotations: + # eks.amazonaws.com/role-arn: "arn:aws:iam:::role/" + + # -- RBAC parameters + rbac: + # -- Create RBAC resources + create: true + # -- Add custom rule to the role + rules: [] + + # -- Set security context for the pod + # @default -- See below + podSecurityContext: + enabled: true + runAsUser: 3000 + runAsGroup: 3000 + fsGroup: 3000 + + # -- Set node selector + nodeSelector: {} + # -- Set resources + resources: {} + # -- Set tolerations + tolerations: [] + # -- Set affinity + affinity: {} + + # -- `dind-lv-monitor` DaemonSet parameters + # (local volumes cleaner) + # @default -- See below + dind-lv-monitor: + enabled: true + image: + registry: quay.io + repository: codefresh/dind-volume-utils + tag: 1.29.4 + podAnnotations: {} + podSecurityContext: + enabled: true + runAsUser: 1000 + fsGroup: 1000 + containerSecurityContext: {} + env: {} + resources: {} + nodeSelector: {} + tolerations: + - key: 'codefresh/dind' + operator: 'Exists' + effect: 'NoSchedule' + volumePermissions: + enabled: true + image: + registry: docker.io + repository: alpine + tag: 3.18 + resources: {} + securityContext: + runAsUser: 0 # auto + + # `dind-volume-cleanup` CronJob parameters + # (external volumes cleaner) + # @default -- See below + dind-volume-cleanup: + enabled: true + image: + registry: quay.io + repository: codefresh/dind-volume-cleanup + tag: 1.2.0 + env: {} + concurrencyPolicy: Forbid + schedule: "*/10 * * * *" + successfulJobsHistory: 3 + failedJobsHistory: 1 + suspend: false + podAnnotations: {} + podSecurityContext: + enabled: true + fsGroup: 3000 + runAsGroup: 3000 + runAsUser: 3000 + nodeSelector: {} + affinity: {} + tolerations: [] + +# Storage parameters for volume-provisioner +# @default -- See below +storage: + # -- Set backend volume type (`local`/`ebs`/`ebs-csi`/`gcedisk`/`azuredisk`) + backend: local + # -- Set filesystem type (`ext4`/`xfs`) + fsType: "ext4" + + # Storage parametrs example for local volumes on the K8S nodes filesystem (i.e. `storage.backend=local`) + # https://kubernetes.io/docs/concepts/storage/volumes/#local + # @default -- See below + local: + # -- Set volume path on the host filesystem + volumeParentDir: /var/lib/codefresh/dind-volumes + + # Storage parameters example for aws ebs disks (i.e. `storage.backend=ebs`/`storage.backend=ebs-csi`) + # https://aws.amazon.com/ebs/ + # https://codefresh.io/docs/docs/installation/codefresh-runner/#aws-backend-volume-configuration + # @default -- See below + ebs: + # -- Set EBS volume type (`gp2`/`gp3`/`io1`) (required) + volumeType: "gp2" + # -- Set EBS volumes availability zone (required) + availabilityZone: "us-east-1a" + # -- Enable encryption (optional) + encrypted: "false" + # -- Set KMS encryption key ID (optional) + kmsKeyId: "" + + # -- Set AWS_ACCESS_KEY_ID for volume-provisioner (optional) + # Ref: https://codefresh.io/docs/docs/installation/codefresh-runner/#dind-volume-provisioner-permissions + accessKeyId: "" + # -- Existing secret containing AWS_ACCESS_KEY_ID. + accessKeyIdSecretKeyRef: {} + # E.g. + # accessKeyIdSecretKeyRef: + # name: + # key: + + # -- Set AWS_SECRET_ACCESS_KEY for volume-provisioner (optional) + # Ref: https://codefresh.io/docs/docs/installation/codefresh-runner/#dind-volume-provisioner-permissions + secretAccessKey: "" + # -- Existing secret containing AWS_SECRET_ACCESS_KEY + secretAccessKeySecretKeyRef: {} + # E.g. + # secretAccessKeySecretKeyRef: + # name: + # key: + + # E.g. + # ebs: + # volumeType: gp3 + # availabilityZone: us-east-1c + # encrypted: false + # iops: "5000" + # # I/O operations per second. Only effetive when gp3 volume type is specified. + # # Default value - 3000. + # # Max - 16,000 + # throughput: "500" + # # Throughput in MiB/s. Only effective when gp3 volume type is specified. + # # Default value - 125. + # # Max - 1000. + # ebs: + # volumeType: gp2 + # availabilityZone: us-east-1c + # encrypted: true + # kmsKeyId: "1234abcd-12ab-34cd-56ef-1234567890ab" + # accessKeyId: "MYKEYID" + # secretAccessKey: "MYACCESSKEY" + + # Storage parameters example for gce disks + # https://cloud.google.com/compute/docs/disks#pdspecs + # https://codefresh.io/docs/docs/installation/codefresh-runner/#gke-google-kubernetes-engine-backend-volume-configuration + # @default -- See below + gcedisk: + # -- Set GCP volume backend type (`pd-ssd`/`pd-standard`) + volumeType: "pd-ssd" + # -- Set GCP volume availability zone + availabilityZone: "us-west1-a" + # -- Set Google SA JSON key for volume-provisioner (optional) + serviceAccountJson: "" + # -- Existing secret containing containing Google SA JSON key for volume-provisioner (optional) + serviceAccountJsonSecretKeyRef: {} + # E.g. + # gcedisk: + # volumeType: pd-ssd + # availabilityZone: us-central1-c + # serviceAccountJson: |- + # { + # "type": "service_account", + # "project_id": "...", + # "private_key_id": "...", + # "private_key": "...", + # "client_email": "...", + # "client_id": "...", + # "auth_uri": "...", + # "token_uri": "...", + # "auth_provider_x509_cert_url": "...", + # "client_x509_cert_url": "..." + # } + + # Storage parameters example for Azure Disks + # https://codefresh.io/docs/docs/installation/codefresh-runner/#install-codefresh-runner-on-azure-kubernetes-service-aks + # @default -- See below + azuredisk: + # -- Set storage type (`Premium_LRS`) + skuName: Premium_LRS + cachingMode: None + # availabilityZone: northeurope-1 + # resourceGroup: + # DiskIOPSReadWrite: 500 + # DiskMBpsReadWrite: 100 + + mountAzureJson: false + +# -- Set runtime parameters +# @default -- See below + +runtime: + # -- Set annotation on engine Service Account + # Ref: https://codefresh.io/docs/docs/administration/codefresh-runner/#injecting-aws-arn-roles-into-the-cluster + serviceAccount: + create: true + annotations: {} + # E.g. + # serviceAccount: + # annotations: + # eks.amazonaws.com/role-arn: "arn:aws:iam:::role/" + + # -- Set parent runtime to inherit. + # Should not be changes. Parent runtime is controlled from Codefresh side. + runtimeExtends: + - system/default/hybrid/k8s_low_limits + # -- Runtime description + description: "" + + # -- RBAC parameters + rbac: + # -- Create RBAC resources + create: true + # -- Add custom rule to the engine role + rules: [] + + # -- (for On-Premise only) Enable agent + agent: true + # -- (for On-Premise only) Set inCluster runtime + inCluster: true + # -- (for On-Premise only) Assign accounts to runtime (list of account ids) + accounts: [] + + # -- Parameters for DinD (docker-in-docker) pod (aka "runtime" pod). + dind: + # -- Set dind image. + image: + registry: quay.io + repository: codefresh/dind + tag: 26.1.4-1.28.7 # use `latest-rootless/rootless/26.1.4-1.28.7-rootless` tags for rootless-dind + pullPolicy: IfNotPresent + # -- Set dind resources. + resources: + requests: null + limits: + cpu: 400m + memory: 800Mi + # -- Set termination grace period. + terminationGracePeriodSeconds: 30 + # -- PV claim spec parametes. + pvcs: + # -- Default dind PVC parameters + dind: + # -- PVC name prefix. + # Keep `dind` as default! Don't change! + name: dind + # -- PVC storage class name. + # Change ONLY if you need to use storage class NOT from Codefresh volume-provisioner + storageClassName: '{{ include "dind-volume-provisioner.storageClassName" . }}' + # -- PVC size. + volumeSize: 16Gi + # -- PV reuse selector. + # Ref: https://codefresh.io/docs/docs/installation/codefresh-runner/#volume-reuse-policy + reuseVolumeSelector: codefresh-app,io.codefresh.accountName + reuseVolumeSortOrder: pipeline_id + # -- PV annotations. + annotations: {} + # E.g.: + # annotations: + # codefresh.io/volume-retention: 7d + # -- Set additional env vars. + env: + DOCKER_ENABLE_DEPRECATED_PULL_SCHEMA_1_IMAGE: true + # -- Set pod annotations. + podAnnotations: {} + # -- Set pod labels. + podLabels: {} + # -- Set node selector. + nodeSelector: {} + # -- Set affinity + affinity: {} + # -- Set tolerations. + tolerations: [] + # -- Set scheduler name. + schedulerName: "" + # -- Set service account for pod. + serviceAccount: codefresh-engine + # -- Keep `true` as default! + userAccess: true + # -- Add extra volumes + userVolumes: {} + # E.g.: + # userVolumes: + # regctl-docker-registry: + # name: regctl-docker-registry + # secret: + # items: + # - key: .dockerconfigjson + # path: config.json + # secretName: regctl-docker-registry + # optional: true + # -- Add extra volume mounts + userVolumeMounts: {} + # E.g.: + # userVolumeMounts: + # regctl-docker-registry: + # name: regctl-docker-registry + # mountPath: /home/appuser/.docker/ + # readOnly: true + + # -- Parameters for Engine pod (aka "pipeline" orchestrator). + engine: + # -- Set image. + image: + registry: quay.io + repository: codefresh/engine + tag: 1.174.12 + pullPolicy: IfNotPresent + # -- Set container command. + command: + - npm + - run + - start + # -- Set resources. + resources: + requests: + cpu: 100m + memory: 128Mi + limits: + cpu: 1000m + memory: 2048Mi + # -- Set termination grace period. + terminationGracePeriodSeconds: 180 + # -- Set system(base) runtime images. + # @default -- See below. + runtimeImages: + COMPOSE_IMAGE: quay.io/codefresh/compose:v2.28.1-1.5.0 + CONTAINER_LOGGER_IMAGE: quay.io/codefresh/cf-container-logger:1.11.6 + DOCKER_BUILDER_IMAGE: quay.io/codefresh/cf-docker-builder:1.3.13 + DOCKER_PULLER_IMAGE: quay.io/codefresh/cf-docker-puller:8.0.17 + DOCKER_PUSHER_IMAGE: quay.io/codefresh/cf-docker-pusher:6.0.16 + DOCKER_TAG_PUSHER_IMAGE: quay.io/codefresh/cf-docker-tag-pusher:1.3.14 + FS_OPS_IMAGE: quay.io/codefresh/fs-ops:1.2.3 + GIT_CLONE_IMAGE: quay.io/codefresh/cf-git-cloner:10.1.28 + KUBE_DEPLOY: quay.io/codefresh/cf-deploy-kubernetes:16.1.11 + PIPELINE_DEBUGGER_IMAGE: quay.io/codefresh/cf-debugger:1.3.0 + TEMPLATE_ENGINE: quay.io/codefresh/pikolo:0.14.1 + CR_6177_FIXER: 'quay.io/codefresh/alpine:edge' + GC_BUILDER_IMAGE: 'quay.io/codefresh/cf-gc-builder:0.5.3' + COSIGN_IMAGE_SIGNER_IMAGE: 'quay.io/codefresh/cf-cosign-image-signer:2.4.0-cf.2' + # -- Set additional env vars. + env: + # -- Interval to check the exec status in the container-logger + CONTAINER_LOGGER_EXEC_CHECK_INTERVAL_MS: 1000 + # -- Timeout while doing requests to the Docker daemon + DOCKER_REQUEST_TIMEOUT_MS: 30000 + # -- If "true", composition images will be pulled sequentially + FORCE_COMPOSE_SERIAL_PULL: false + # -- Level of logging for engine + LOGGER_LEVEL: debug + # -- Enable debug-level logging of outgoing HTTP/HTTPS requests + LOG_OUTGOING_HTTP_REQUESTS: false + # -- Enable emitting metrics from engine + METRICS_PROMETHEUS_ENABLED: true + # -- Enable legacy metrics + METRICS_PROMETHEUS_ENABLE_LEGACY_METRICS: false + # -- Enable collecting process metrics + METRICS_PROMETHEUS_COLLECT_PROCESS_METRICS: false + # -- Host for Prometheus metrics server + METRICS_PROMETHEUS_HOST: '0.0.0.0' + # -- Port for Prometheus metrics server + METRICS_PROMETHEUS_PORT: 9100 + # -- Set workflow limits. + workflowLimits: + # -- Maximum time allowed to the engine to wait for the pre-steps (aka "Initializing Process") to succeed; seconds. + MAXIMUM_ALLOWED_TIME_BEFORE_PRE_STEPS_SUCCESS: 600 + # -- Maximum time for workflow execution; seconds. + MAXIMUM_ALLOWED_WORKFLOW_AGE_BEFORE_TERMINATION: 86400 + # -- Maximum time allowed to workflow to spend in "elected" state; seconds. + MAXIMUM_ELECTED_STATE_AGE_ALLOWED: 900 + # -- Maximum retry attempts allowed for workflow. + MAXIMUM_RETRY_ATTEMPTS_ALLOWED: 20 + # -- Maximum time allowed to workflow to spend in "terminating" state until force terminated; seconds. + MAXIMUM_TERMINATING_STATE_AGE_ALLOWED: 900 + # -- Maximum time allowed to workflow to spend in "terminating" state without logs activity until force terminated; seconds. + MAXIMUM_TERMINATING_STATE_AGE_ALLOWED_WITHOUT_UPDATE: 300 + # -- Time since the last health check report after which workflow is terminated; seconds. + TIME_ENGINE_INACTIVE_UNTIL_TERMINATION: 300 + # -- Time since the last health check report after which the engine is considered unhealthy; seconds. + TIME_ENGINE_INACTIVE_UNTIL_UNHEALTHY: 60 + # -- Time since the last workflow logs activity after which workflow is terminated; seconds. + TIME_INACTIVE_UNTIL_TERMINATION: 2700 + # -- Set pod annotations. + podAnnotations: {} + # -- Set pod labels. + podLabels: {} + # -- Set node selector. + nodeSelector: {} + # -- Set affinity + affinity: {} + # -- Set tolerations. + tolerations: [] + # -- Set scheduler name. + schedulerName: "" + # -- Set service account for pod. + serviceAccount: codefresh-engine + # -- Set extra env vars + userEnvVars: [] + # E.g. + # userEnvVars: + # - name: GITHUB_TOKEN + # valueFrom: + # secretKeyRef: + # name: github-token + # key: token + + # -- Parameters for `runtime-patch` post-upgrade/install hook + # @default -- See below + patch: + enabled: true + image: + registry: quay.io + repository: codefresh/cli + tag: 0.85.0-rootless + rbac: + enabled: true + annotations: {} + affinity: {} + nodeSelector: {} + podSecurityContext: {} + resources: {} + tolerations: [] + ttlSecondsAfterFinished: 180 + env: + HOME: /tmp + + # -- Parameters for `gencerts-dind` post-upgrade/install hook + # @default -- See below + gencerts: + enabled: true + image: + registry: quay.io + repository: codefresh/kubectl + tag: 1.28.4 + rbac: + enabled: true + annotations: {} + affinity: {} + nodeSelector: {} + podSecurityContext: {} + resources: {} + tolerations: [] + ttlSecondsAfterFinished: 180 + + # -- DinD pod daemon config + # @default -- See below + dindDaemon: + hosts: + - unix:///var/run/docker.sock + - tcp://0.0.0.0:1300 + tlsverify: true + tls: true + tlscacert: /etc/ssl/cf-client/ca.pem + tlscert: /etc/ssl/cf/server-cert.pem + tlskey: /etc/ssl/cf/server-key.pem + insecure-registries: + - 192.168.99.100:5000 + metrics-addr: 0.0.0.0:9323 + experimental: true + +# App-Proxy parameters +# Ref: https://codefresh.io/docs/docs/installation/codefresh-runner/#app-proxy-installation +# @default -- See below +appProxy: + # -- Enable app-proxy + enabled: false + # -- Set number of pods + replicasCount: 1 + # -- Upgrade strategy + updateStrategy: + type: RollingUpdate + # -- Set pod annotations + podAnnotations: {} + + # -- Set image + image: + registry: quay.io + repository: codefresh/cf-app-proxy + tag: 0.0.47 + # -- Add additional env vars + env: {} + + # Set app-proxy ingress parameters + # @default -- See below + ingress: + # -- Set path prefix for ingress (keep empty for default `/` path) + pathPrefix: "" + # -- Set ingress class + class: "" + # -- Set DNS hostname the ingress will use + host: "" + # -- Set k8s tls secret for the ingress object + tlsSecret: "" + # -- Set extra annotations for ingress object + annotations: {} + # E.g. + # ingress: + # pathPrefix: "/cf-app-proxy" + # class: "nginx" + # host: "mydomain.com" + # tlsSecret: "tls-cert-app-proxy" + # annotations: + # nginx.ingress.kubernetes.io/whitelist-source-range: 123.123.123.123/130 + + # -- Service Account parameters + serviceAccount: + # -- Create service account + create: true + # -- Override service account name + name: "" + # -- Use Role(true)/ClusterRole(true) + namespaced: true + # -- Additional service account annotations + annotations: {} + + # -- RBAC parameters + rbac: + # -- Create RBAC resources + create: true + # -- Use Role(true)/ClusterRole(true) + namespaced: true + # -- Add custom rule to the role + rules: [] + + # -- Set security context for the pod + podSecurityContext: {} + + # -- Readiness probe configuration + # @default -- See below + readinessProbe: + failureThreshold: 5 + initialDelaySeconds: 5 + periodSeconds: 5 + successThreshold: 1 + timeoutSeconds: 5 + + # -- Set requests and limits + resources: {} + # -- Set node selector + nodeSelector: {} + # -- Set tolerations + tolerations: [] + # -- Set affinity + affinity: {} + +# Monitor parameters +# @default -- See below +monitor: + # -- Enable monitor + # Ref: https://codefresh.io/docs/docs/installation/codefresh-runner/#install-monitoring-component + enabled: false + + # -- Set number of pods + replicasCount: 1 + # -- Upgrade strategy + updateStrategy: + type: RollingUpdate + # -- Set pod annotations + podAnnotations: {} + + # -- Set image + image: + registry: quay.io + repository: codefresh/cf-k8s-agent + tag: 1.3.18 + # -- Add additional env vars + env: {} + + # -- Service Account parameters + serviceAccount: + # -- Create service account + create: true + # -- Override service account name + name: "" + # -- Additional service account annotations + annotations: {} + + # -- RBAC parameters + rbac: + # -- Create RBAC resources + create: true + # -- Use Role(true)/ClusterRole(true) + namespaced: true + # -- Add custom rule to the role + rules: [] + + # -- Readiness probe configuration + # @default -- See below + readinessProbe: + failureThreshold: 5 + initialDelaySeconds: 5 + periodSeconds: 5 + successThreshold: 1 + timeoutSeconds: 5 + + podSecurityContext: {} + + # -- Set node selector + nodeSelector: {} + # -- Set resources + resources: {} + # -- Set tolerations + tolerations: [] + # -- Set affinity + affinity: {} + +# -- Add serviceMonitor +# @default -- See below +serviceMonitor: + main: + # -- Enable service monitor for dind pods + enabled: false + nameOverride: dind + selector: + matchLabels: + app: dind + endpoints: + - path: /metrics + targetPort: 9100 + relabelings: + - action: labelmap + regex: __meta_kubernetes_pod_label_(.+) + +# -- Add podMonitor (for engine pods) +# @default -- See below +podMonitor: + main: + # -- Enable pod monitor for engine pods + enabled: false + nameOverride: engine + selector: + matchLabels: + app: runtime + podMetricsEndpoints: + - path: /metrics + targetPort: 9100 + + runner: + # -- Enable pod monitor for runner pod + enabled: false + nameOverride: runner + selector: + matchLabels: + codefresh.io/application: runner + podMetricsEndpoints: + - path: /metrics + targetPort: 8080 + + volume-provisioner: + # -- Enable pod monitor for volumeProvisioner pod + enabled: false + nameOverride: volume-provisioner + selector: + matchLabels: + codefresh.io/application: volume-provisioner + podMetricsEndpoints: + - path: /metrics + targetPort: 8080 + +# -- Event exporter parameters +# @default -- See below +event-exporter: + # -- Enable event-exporter + enabled: false + # -- Set number of pods + replicasCount: 1 + # -- Upgrade strategy + updateStrategy: + type: Recreate + # -- Set pod annotations + podAnnotations: {} + + # -- Set image + image: + registry: docker.io + repository: codefresh/k8s-event-exporter + tag: latest + # -- Add additional env vars + env: {} + + # -- Service Account parameters + serviceAccount: + # -- Create service account + create: true + # -- Override service account name + name: "" + # -- Additional service account annotations + annotations: {} + + # -- RBAC parameters + rbac: + # -- Create RBAC resources + create: true + # -- Add custom rule to the role + rules: [] + + # -- Set security context for the pod + # @default -- See below + podSecurityContext: + enabled: false + + # -- Set node selector + nodeSelector: {} + # -- Set resources + resources: {} + # -- Set tolerations + tolerations: [] + # -- Set affinity + affinity: {} + +# -- Array of extra objects to deploy with the release +extraResources: [] +# E.g. +# extraResources: +# - apiVersion: rbac.authorization.k8s.io/v1 +# kind: ClusterRole +# metadata: +# name: codefresh-role +# rules: +# - apiGroups: [ "*"] +# resources: ["*"] +# verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] +# - apiVersion: v1 +# kind: ServiceAccount +# metadata: +# name: codefresh-user +# namespace: "{{ .Release.Namespace }}" +# - apiVersion: rbac.authorization.k8s.io/v1 +# kind: ClusterRoleBinding +# metadata: +# name: codefresh-user +# roleRef: +# apiGroup: rbac.authorization.k8s.io +# kind: ClusterRole +# name: codefresh-role +# subjects: +# - kind: ServiceAccount +# name: codefresh-user +# namespace: "{{ .Release.Namespace }}" +# - apiVersion: v1 +# kind: Secret +# type: kubernetes.io/service-account-token +# metadata: +# name: codefresh-user-token +# namespace: "{{ .Release.Namespace }}" +# annotations: +# kubernetes.io/service-account.name: "codefresh-user" diff --git a/charts/dell/csi-powerstore/2.11.1/Chart.yaml b/charts/dell/csi-powerstore/2.11.1/Chart.yaml new file mode 100644 index 0000000000..c600f96b8a --- /dev/null +++ b/charts/dell/csi-powerstore/2.11.1/Chart.yaml @@ -0,0 +1,23 @@ +annotations: + catalog.cattle.io/certified: partner + catalog.cattle.io/display-name: Dell CSI PowerStore + catalog.cattle.io/kube-version: '>= 1.24.0' + catalog.cattle.io/release-name: powerstore +apiVersion: v2 +appVersion: 2.11.1 +description: 'PowerStore CSI (Container Storage Interface) driver Kubernetes integration. + This chart includes everything required to provision via CSI as well as a PowerStore + StorageClass. ' +home: https://github.com/dell/csi-powerstore +icon: file://assets/icons/csi-powerstore.png +keywords: +- csi +- storage +kubeVersion: '>= 1.24.0' +maintainers: +- name: DellEMC +name: csi-powerstore +sources: +- https://github.com/dell/csi-powerstore +type: application +version: 2.11.1 diff --git a/charts/dell/csi-powerstore/2.11.1/app-readme.md b/charts/dell/csi-powerstore/2.11.1/app-readme.md new file mode 100644 index 0000000000..64441099be --- /dev/null +++ b/charts/dell/csi-powerstore/2.11.1/app-readme.md @@ -0,0 +1,92 @@ +# CSI Driver for Dell PowerStore Helm chart + +The [CSI Driver for Dell PowerStore](https://github.com/dell/csi-powerstore) is part of the CSM (Container Storage Modules) open-source suite of Kubernetes storage enablers for Dell EMC products. CSI Driver for PowerStore is a Container Storage Interface (CSI) driver that provides support for provisioning persistent storage using Dell EMC PowerStore storage array. + +## Prerequisites + +- Kubernetes version >= 1.23 (see [supported version](https://dell.github.io/csm-docs/docs/csidriver/#features-and-capabilities)) +- Helm 3 +- If you plan to use either the Fibre Channel or iSCSI or NVMe/TCP or NVMe/FC protocol, refer to either _Fibre Channel requirements_ or _Set up the iSCSI Initiator_ or _Set up the NVMe Initiator_ sections below. You can use NFS volumes without FC or iSCSI or NVMe/TCP or NVMe/FC configuration. +> You can use either the Fibre Channel or iSCSI or NVMe/TCP or NVMe/FC protocol, but you do not need all the four. + +> If you want to use preconfigured iSCSI/FC hosts be sure to check that they are not part of any host group +- Linux native multipathing requirements +- Mount propagation is enabled on container runtime that is being used +- If using Snapshot feature, satisfy all Volume Snapshot requirements +- Nonsecure registries are defined in Docker or other container runtimes, for CSI drivers that are hosted in a non-secure location. +- You can access your cluster with kubectl and helm. +- Ensure that your nodes support mounting NFS volumes. +- Install the Volume Snapshot CRDs by referring to [this](https://dell.github.io/csm-docs/docs/csidriver/installation/helm/powerstore/#optional-volume-snapshot-requirements) page. + +> Refer [this](https://dell.github.io/csm-docs/docs/csidriver/installation/helm/powerstore/#prerequisites) for setting up the prerequisites. + +## Optional Features +- [Volume Snapshot](https://dell.github.io/csm-docs/docs/csidriver/installation/helm/powerstore/#optional-volume-snapshot-requirements) +- [Volume Health Monitoring](https://dell.github.io/csm-docs/docs/csidriver/installation/helm/powerstore/#volume-health-monitoring) +- [Replication](https://dell.github.io/csm-docs/docs/csidriver/installation/helm/powerstore/#optional-replication-feature-requirements) + +## Install the Driver +**Steps** +1. Create a namespace where you want to install the driver (e.g. "csi-powerstore"). You can choose any name for the namespace, but make sure to align to the same namespace during the whole installation. +2. Create a secret named "powerstore-config" in the namespace created above. Sample [secret.yaml](https://github.com/dell/csi-powerstore/blob/main/samples/secret/secret.yaml). + >Secret must be of type opaque. +3. Create storage classes using ones from [samples](https://github.com/dell/csi-powerstore/tree/main/samples/storageclass) folder as an example. + > If you do not specify `arrayID` parameter in the storage class then the array that was specified as the default would be used for provisioning volumes. +4. Install the chart with the name "powerstore". The value.yaml file used during installation can be found [here](https://github.com/dell/csi-powerstore/blob/main/helm/csi-powerstore/values.yaml) + +The following table lists the configurable parameters of the chart and their default values. + +| Parameter | Description | Required | Default | +|-------------------------------------|-----------------------------------------------------------------------------------------------------------|----------|----------------------------| +| logLevel | Defines CSI driver log level | No | "debug" | +| logFormat | Defines CSI driver log format | No | "JSON" | +| externalAccess | Defines additional entries for hostAccess of NFS volumes, single IP address and subnet are valid entries | No | " " | +| kubeletConfigDir | Defines kubelet config path for cluster | Yes | "/var/lib/kubelet" | +| imagePullPolicy | Policy to determine if the image should be pulled prior to starting the container. | Yes | "IfNotPresent" | +| nfsAcls | Defines permissions - POSIX mode bits or NFSv4 ACLs, to be set on NFS target mount directory. | No | "0777" | +| connection.enableCHAP | Defines whether the driver should use CHAP for iSCSI connections or not | No | False | +| controller.controllerCount | Defines number of replicas of controller deployment | Yes | 2 | +| controller.volumeNamePrefix | Defines the string added to each volume that the CSI driver creates | No | "csivol" | +| controller.snapshot.enabled | Allows to enable/disable snapshotter sidecar with driver installation for snapshot feature | No | "true" | +| controller.snapshot.snapNamePrefix | Defines prefix to apply to the names of a created snapshots | No | "csisnap" | +| controller.resizer.enabled | Allows to enable/disable resizer sidecar with driver installation for volume expansion feature | No | "true" | +| controller.healthMonitor.enabled | Allows to enable/disable volume health monitor | No | false | +| controller.healthMonitor.interval | Interval of monitoring volume health condition | No | 60s | +| controller.nodeSelector | Defines what nodes would be selected for pods of controller deployment | Yes | " " | +| controller.tolerations | Defines toleration that would be applied to controller deployment | Yes | " " | +| node.nodeNamePrefix | Defines the string added to each node that the CSI driver registers | No | "csi-node" | +| node.nodeIDPath | Defines a path to file with a unique identifier identifying the node in the Kubernetes cluster | No | "/etc/machine-id" | +| node.healthMonitor.enabled | Allows to enable/disable volume health monitor | No | false | +| node.nodeSelector | Defines what nodes would be selected for pods of node daemonset | Yes | " " | +| node.tolerations | Defines toleration that would be applied to node daemonset | Yes | " " | +| fsGroupPolicy | Defines which FS Group policy mode to be used, Supported modes `None, File and ReadWriteOnceWithFSType` | No | "ReadWriteOnceWithFSType" | +| controller.vgsnapshot.enabled | To enable or disable the volume group snapshot feature | No | "true" | +| images.driverRepository | To use an image from custom repository | No | dockerhub | +| version | To use any driver version | No | Latest driver version | +| allowAutoRoundOffFilesystemSize | Allows the controller to round off filesystem to 3Gi which is the minimum supported value | No | false | +| storageCapacity.enabled | Enable/Disable storage capacity tracking | No | true | +| storageCapacity.pollInterval | Configure how often the driver checks for changed capacity | No | 5m | + +*NOTE:* +- By default, the driver scans available SCSI adapters and tries to register them with the storage array under the SCSI hostname using `node.nodeNamePrefix` and the ID read from the file pointed to by `node.nodeIDPath`. If an adapter is already registered with the storage under a different hostname, the adapter is not used by the driver. +- A hostname the driver uses for registration of adapters is in the form `--`. By default, these are csi-node and the machine ID read from the file `/etc/machine-id`. +- To customize the hostname, for example if you want to make them more user friendly, adjust nodeIDPath and nodeNamePrefix accordingly. For example, you can set `nodeNamePrefix` to `k8s` and `nodeIDPath` to `/etc/hostname` to produce names such as `k8s-worker1-192.168.1.2`. +- (Optional) Enable additional Mount Options - A user is able to specify additional mount options as needed for the driver. + - Mount options are specified in storageclass yaml under _mountOptions_. + - *WARNING*: Before utilizing mount options, you must first be fully aware of the potential impact and understand your environment's requirements for the specified option. + +## Support + +The CSI Driver for Dell PowerStore is fully supported by DELL. + +For all your support needs or to follow the latest ongoing discussions and updates, join our Slack group. Click [Here](http://del.ly/Slack_request) to request your invite. + +You can also interact with us on [GitHub](https://github.com/dell/csm) by creating a [GitHub Issue](https://github.com/dell/csm/issues). + +## Contributing + +We value all feedback and contributions. If you find any issues or want to contribute, please feel free to open an issue or file a PR. More details in [Contribution Guidelines](https://dell.github.io/csm-docs/docs/references/contributionguidelines/). + +## License + +This is open source software licensed using the Apache License 2.0. Please see [LICENSE](https://github.com/dell/csi-powerstore/blob/main/licenses/Apache.txt) for details. diff --git a/charts/dell/csi-powerstore/2.11.1/templates/_helpers.tpl b/charts/dell/csi-powerstore/2.11.1/templates/_helpers.tpl new file mode 100644 index 0000000000..cdbe7adac9 --- /dev/null +++ b/charts/dell/csi-powerstore/2.11.1/templates/_helpers.tpl @@ -0,0 +1,10 @@ +{{/* +Return true if storage capacity tracking is enabled and is supported based on k8s version +*/}} +{{- define "csi-powerstore.isStorageCapacitySupported" -}} +{{- if eq .Values.storageCapacity.enabled true -}} + {{- if and (eq .Capabilities.KubeVersion.Major "1") (ge (trimSuffix "+" .Capabilities.KubeVersion.Minor) "24") -}} + {{- true -}} + {{- end -}} +{{- end -}} +{{- end -}} diff --git a/charts/dell/csi-powerstore/2.11.1/templates/controller.yaml b/charts/dell/csi-powerstore/2.11.1/templates/controller.yaml new file mode 100644 index 0000000000..576977dbd6 --- /dev/null +++ b/charts/dell/csi-powerstore/2.11.1/templates/controller.yaml @@ -0,0 +1,457 @@ +# +# +# Copyright © 2020-2023 Dell Inc. or its subsidiaries. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# + +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Release.Name }}-controller + namespace: {{ .Release.Namespace }} + +--- + +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ .Release.Name }}-controller +rules: + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "watch", "list", "delete", "update", "create"] + - apiGroups: [""] + resources: ["events"] + verbs: ["list", "watch", "create", "update", "patch"] + - apiGroups: [""] + resources: ["nodes"] + {{- if hasKey .Values "podmon" }} + {{- if eq .Values.podmon.enabled true }} + verbs: ["get", "list", "watch", "patch"] + {{- else }} + verbs: ["get", "list", "watch"] + {{- end }} + {{- end }} + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch", "create", "delete", "update", "patch"] + - apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["get", "list", "watch", "update"] + - apiGroups: ["storage.k8s.io"] + resources: ["storageclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments"] + {{- if hasKey .Values "podmon" }} + {{- if eq .Values.podmon.enabled true }} + verbs: ["get", "list", "watch", "update", "patch", "delete"] + {{- else }} + verbs: ["get", "list", "watch", "update", "patch"] + {{- end }} + {{- end }} + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "list"] + {{- if hasKey .Values.controller "vgsnapshot" }} + {{- if eq .Values.controller.vgsnapshot.enabled true }} + - apiGroups: ["volumegroup.storage.dell.com"] + resources: ["dellcsivolumegroupsnapshots","dellcsivolumegroupsnapshots/status"] + verbs: ["create", "list", "watch", "delete", "update"] + {{- end }} + {{- end }} + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents"] + verbs: ["create", "get", "list", "watch", "update", "delete", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents/status"] + verbs: ["update", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots", "volumesnapshots/status"] + {{- if hasKey .Values.controller "vgsnapshot" }} + {{- if eq .Values.controller.vgsnapshot.enabled true }} + verbs: ["get", "list", "watch", "update", "create", "delete"] + {{- else }} + verbs: ["get", "list", "watch", "update"] + {{- end }} + {{- end }} + - apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments/status"] + verbs: ["patch"] + - apiGroups: [""] + resources: ["pods"] + {{- if hasKey .Values "podmon" }} + {{- if eq .Values.podmon.enabled true }} + verbs: ["get", "list", "watch", "update", "delete"] + {{- else }} + verbs: ["get", "list", "watch"] + {{- end }} + {{- end }} + - apiGroups: ["apiextensions.k8s.io"] + resources: ["customresourcedefinitions"] + verbs: ["create", "list", "watch", "delete"] + - apiGroups: ["storage.k8s.io"] + resources: ["csinodes"] + verbs: ["get", "list", "watch"] + # below for resizer + - apiGroups: [""] + resources: ["persistentvolumeclaims/status"] + verbs: ["update", "patch"] + # below for dell-csi-replicator + {{- if hasKey .Values.controller "replication" }} + {{- if eq .Values.controller.replication.enabled true}} + - apiGroups: ["replication.storage.dell.com"] + resources: ["dellcsireplicationgroups"] + verbs: ["create", "delete", "get", "list", "patch", "update", "watch"] + - apiGroups: ["replication.storage.dell.com"] + resources: ["dellcsireplicationgroups/status"] + verbs: ["get", "patch", "update"] + - apiGroups: [""] + resources: ["configmaps"] + verbs: ["create", "delete", "get", "list", "watch", "update", "patch"] + {{- end}} + {{- end}} + # Permissions for CSIStorageCapacity + {{- if eq (include "csi-powerstore.isStorageCapacitySupported" .) "true" }} + - apiGroups: ["storage.k8s.io"] + resources: ["csistoragecapacities"] + verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] + - apiGroups: [""] + resources: ["pods"] + verbs: ["get"] + - apiGroups: ["apps"] + resources: ["replicasets"] + verbs: ["get"] + {{- end }} +--- + +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ .Release.Name }}-controller +subjects: + - kind: ServiceAccount + name: {{ .Release.Name }}-controller + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: {{ .Release.Name }}-controller + apiGroup: rbac.authorization.k8s.io + +--- + +kind: Deployment +apiVersion: apps/v1 +metadata: + name: {{ .Release.Name }}-controller + namespace: {{ .Release.Namespace }} +spec: + selector: + matchLabels: + name: {{ .Release.Name }}-controller + {{- if lt (.Values.controller.controllerCount | toString | atoi ) 1 -}} + {{- fail "value for .Values.controller.controllerCount should be atleast 1" }} + {{- else }} + replicas: {{ required "Must provide the number of controller instances to create." .Values.controller.controllerCount }} + {{- end }} + template: + metadata: + labels: + name: {{ .Release.Name }}-controller + annotations: + kubectl.kubernetes.io/default-container: driver + spec: + {{ if .Values.controller.nodeSelector }} + nodeSelector: + {{- toYaml .Values.controller.nodeSelector | nindent 8 }} + {{ end }} + {{ if .Values.controller.tolerations }} + tolerations: + {{- toYaml .Values.controller.tolerations | nindent 6 }} + {{ end }} + serviceAccountName: {{ .Release.Name }}-controller + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: "name" + operator: In + values: + - {{ .Release.Name }}-controller + topologyKey: "kubernetes.io/hostname" + containers: + {{- if hasKey .Values "podmon" }} + {{- if eq .Values.podmon.enabled true }} + - name: podmon + image: {{ required "Must provide the podmon container image." .Values.images.podmon }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + args: + {{- toYaml .Values.podmon.controller.args | nindent 12 }} + env: + - name: MY_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: MY_POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: MY_POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + volumeMounts: + - name: socket-dir + mountPath: /var/run/csi + - name: powerstore-config-params + mountPath: /powerstore-config-params + {{- end }} + {{- end }} + {{- if hasKey .Values "dev" }} + {{ if .Values.dev.enableTracing }}{{- include "pstore.tracing" . | nindent 8 }}{{ end }} + {{- end }} + - name: attacher + image: {{ required "Must provide the CSI attacher container image." .Values.images.attacher }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + args: + - "--csi-address=$(ADDRESS)" + - "--v=5" + - "--leader-election" + - "--worker-threads=130" + - "--resync=10s" + - "--timeout=130s" + env: + - name: ADDRESS + value: /var/run/csi/csi.sock + volumeMounts: + - name: socket-dir + mountPath: /var/run/csi + {{- if hasKey .Values.controller "resizer" }} + {{- if eq .Values.controller.resizer.enabled true }} + - name: resizer + image: {{ required "Must provide the CSI resizer container image." .Values.images.resizer }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + args: + - "--csi-address=$(ADDRESS)" + - "--v=5" + - "--leader-election" + env: + - name: ADDRESS + value: /var/run/csi/csi.sock + volumeMounts: + - name: socket-dir + mountPath: /var/run/csi + {{end}} + {{end}} + - name: provisioner + image: {{ required "Must provide the CSI provisioner container image." .Values.images.provisioner }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + args: + - "--csi-address=$(ADDRESS)" + - "--volume-name-prefix={{ required "Must provide a value to prefix to driver created volume names" .Values.controller.volumeNamePrefix }}" + - "--volume-name-uuid-length=10" + - "--v=5" + - "--leader-election" + - "--default-fstype={{ .Values.defaultFsType | default "ext4" }}" + - "--extra-create-metadata" + - "--feature-gates=Topology=true" + - "--enable-capacity={{ (include "csi-powerstore.isStorageCapacitySupported" .) | default false }}" + - "--capacity-ownerref-level=2" + - "--capacity-poll-interval={{ .Values.storageCapacity.pollInterval | default "5m" }}" + env: + - name: ADDRESS + value: /var/run/csi/csi.sock + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + volumeMounts: + - name: socket-dir + mountPath: /var/run/csi + {{- if hasKey .Values.controller "snapshot" }} + {{- if eq .Values.controller.snapshot.enabled true }} + - name: snapshotter + image: {{ required "Must provide the CSI snapshotter container image." .Values.images.snapshotter }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + args: + - "--csi-address=$(ADDRESS)" + - "--v=5" + - "--leader-election" + - "--snapshot-name-prefix={{ required "Must privided a Snapshot Name Prefix" .Values.controller.snapshot.snapNamePrefix }}" + env: + - name: ADDRESS + value: /var/run/csi/csi.sock + volumeMounts: + - name: socket-dir + mountPath: /var/run/csi + {{end}} + {{end}} + {{- if hasKey .Values.controller "vgsnapshot" }} + {{- if eq .Values.controller.vgsnapshot.enabled true }} + - name: vg-snapshotter + image: {{ required "Must provide the vgsnapshotter container image." .Values.images.vgsnapshotter }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + env: + - name: ADDRESS + value: /var/run/csi/csi.sock + volumeMounts: + - name: socket-dir + mountPath: /var/run/csi + {{- end }} + {{- end }} + {{- if hasKey .Values.controller "replication" }} + {{- if eq .Values.controller.replication.enabled true}} + - name: dell-csi-replicator + image: {{ required "Must provide the Dell CSI Replicator image." .Values.images.replication }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + args: + - "--csi-address=$(ADDRESS)" + - "--leader-election=true" + - "--worker-threads=2" + - "--retry-interval-start=1s" + - "--retry-interval-max=300s" + - "--timeout=300s" + - "--context-prefix={{ .Values.controller.replication.replicationContextPrefix}}" + - "--prefix={{ .Values.controller.replication.replicationPrefix}}" + env: + - name: ADDRESS + value: /var/run/csi/csi.sock + - name: X_CSI_REPLICATION_CONFIG_DIR + value: /powerstore-config-params + - name: X_CSI_REPLICATION_CONFIG_FILE_NAME + value: driver-config-params.yaml + volumeMounts: + - name: socket-dir + mountPath: /var/run/csi + - name: powerstore-config-params + mountPath: /powerstore-config-params + {{- end }} + {{- end }} + {{- if hasKey .Values.controller "healthMonitor" }} + {{- if eq .Values.controller.healthMonitor.enabled true}} + - name: csi-external-health-monitor-controller + image: {{ required "Must provide the CSI external health monitor controller image." .Values.images.healthmonitor }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + args: + - "--v=5" + - "--csi-address=$(ADDRESS)" + - "--leader-election" + - "--http-endpoint=:8080" + - "--enable-node-watcher=true" + - "--monitor-interval={{ .Values.controller.healthMonitor.interval | default "60s" }}" + - "--timeout=180s" + env: + - name: ADDRESS + value: /var/run/csi/csi.sock + volumeMounts: + - name: socket-dir + mountPath: /var/run/csi + {{- end }} + {{- end }} + - name: csi-metadata-retriever + image: {{ required "Must provide the CSI Metadata retriever container image." .Values.images.metadataretriever }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + command: [ "/csi-metadata-retriever" ] + env: + {{- if hasKey .Values "dev" }} + - name: ENABLE_TRACING + value: {{ .Values.dev.enableTracing | quote }} + {{ if .Values.dev.enableTracing }}{{- include "pstore.tracingenvvars" . | nindent 12 }}{{ end }} + {{- end }} + - name: CSI_RETRIEVER_ENDPOINT + value: /var/run/csi/csi_retriever.sock + volumeMounts: + - name: socket-dir + mountPath: /var/run/csi + - name: driver + image: {{ required "Must provide the PowerStore driver image repository." .Values.images.driver }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + command: [ "/csi-powerstore" ] + env: + {{- if hasKey .Values "dev" }} + - name: ENABLE_TRACING + value: {{ .Values.dev.enableTracing | quote }} + {{ if .Values.dev.enableTracing }}{{- include "pstore.tracingenvvars" . | nindent 12 }}{{ end }} + {{- end }} + - name: CSI_ENDPOINT + value: /var/run/csi/csi.sock + - name: CSI_RETRIEVER_ENDPOINT + value: /var/run/csi/csi_retriever.sock + - name: X_CSI_MODE + value: controller + - name: X_CSI_DRIVER_NAME + value: {{ .Values.driverName }} + - name: X_CSI_POWERSTORE_EXTERNAL_ACCESS + value: {{ .Values.externalAccess }} + - name: X_CSI_NFS_ACLS + value: "{{ .Values.nfsAcls }}" + - name: X_CSI_POWERSTORE_CONFIG_PATH + value: /powerstore-config/config + - name: X_CSI_POWERSTORE_CONFIG_PARAMS_PATH + value: /powerstore-config-params/driver-config-params.yaml + {{- if hasKey .Values "podmon" }} + - name: X_CSI_PODMON_ENABLED + value: "{{ .Values.podmon.enabled }}" + {{- if eq .Values.podmon.enabled true }} + {{- range $key, $value := .Values.podmon.controller.args }} + {{- if contains "--arrayConnectivityPollRate" $value }} + - name: X_CSI_PODMON_ARRAY_CONNECTIVITY_POLL_RATE + value: "{{ (split "=" $value)._1 }}" + {{- end }} + {{- end }} + {{- end }} + {{- end }} + - name: X_CSI_PODMON_API_PORT + value: "{{ .Values.podmonAPIPort }}" + {{- if hasKey .Values.controller "replication" }} + {{- if eq .Values.controller.replication.enabled true}} + - name: X_CSI_REPLICATION_CONTEXT_PREFIX + value: {{ .Values.controller.replication.replicationContextPrefix | default "powerstore"}} + - name: X_CSI_REPLICATION_PREFIX + value: {{ .Values.controller.replication.replicationPrefix | default "replication.storage.dell.com"}} + {{- end }} + {{- end }} + {{- if hasKey .Values.controller "healthMonitor" }} + {{- if eq .Values.controller.healthMonitor.enabled true}} + - name: X_CSI_HEALTH_MONITOR_ENABLED + value: "{{ .Values.controller.healthMonitor.enabled }}" + {{- end }} + {{- end }} + - name: GOPOWERSTORE_DEBUG + value: "true" + - name: CSI_AUTO_ROUND_OFF_FILESYSTEM_SIZE + value: "{{ .Values.allowAutoRoundOffFilesystemSize | default true }}" + volumeMounts: + - name: socket-dir + mountPath: /var/run/csi + - name: powerstore-config + mountPath: /powerstore-config + - name: powerstore-config-params + mountPath: /powerstore-config-params + volumes: + - name: socket-dir + emptyDir: + - name: powerstore-config-params + configMap: + name: {{ .Release.Name }}-config-params + - name: powerstore-config + secret: + secretName: {{ .Release.Name }}-config diff --git a/charts/dell/csi-powerstore/2.11.1/templates/csidriver.yaml b/charts/dell/csi-powerstore/2.11.1/templates/csidriver.yaml new file mode 100644 index 0000000000..9f5ad9be43 --- /dev/null +++ b/charts/dell/csi-powerstore/2.11.1/templates/csidriver.yaml @@ -0,0 +1,27 @@ +# +# +# Copyright © 2020-2023 Dell Inc. or its subsidiaries. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# + +apiVersion: storage.k8s.io/v1 +kind: CSIDriver +metadata: + name: {{ .Values.driverName }} +spec: + storageCapacity: {{ (include "csi-powerstore.isStorageCapacitySupported" .) | default false }} + podInfoOnMount: true + fsGroupPolicy: {{ .Values.fsGroupPolicy }} + volumeLifecycleModes: + - Persistent + - Ephemeral diff --git a/charts/dell/csi-powerstore/2.11.1/templates/driver-config-params.yaml b/charts/dell/csi-powerstore/2.11.1/templates/driver-config-params.yaml new file mode 100644 index 0000000000..ce5349de29 --- /dev/null +++ b/charts/dell/csi-powerstore/2.11.1/templates/driver-config-params.yaml @@ -0,0 +1,31 @@ +# +# +# Copyright © 2021-2023 Dell Inc. or its subsidiaries. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# + +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-config-params + namespace: {{ .Release.Namespace }} +data: + driver-config-params.yaml: | + CSI_LOG_LEVEL: "{{ .Values.logLevel }}" + CSI_LOG_FORMAT: "{{ .Values.logFormat }}" + {{ if .Values.podmon.enabled }} + PODMON_CONTROLLER_LOG_LEVEL: "{{ .Values.logLevel }}" + PODMON_CONTROLLER_LOG_FORMAT: "{{ .Values.logFormat }}" + PODMON_NODE_LOG_LEVEL: "{{ .Values.logLevel }}" + PODMON_NODE_LOG_FORMAT: "{{ .Values.logFormat }}" + {{ end }} \ No newline at end of file diff --git a/charts/dell/csi-powerstore/2.11.1/templates/node.yaml b/charts/dell/csi-powerstore/2.11.1/templates/node.yaml new file mode 100644 index 0000000000..1ee7969615 --- /dev/null +++ b/charts/dell/csi-powerstore/2.11.1/templates/node.yaml @@ -0,0 +1,353 @@ +# +# +# Copyright © 2020-2023 Dell Inc. or its subsidiaries. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# + +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Release.Name }}-node + namespace: {{ .Release.Namespace }} + +--- + +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ .Release.Name }}-node +rules: + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["create", "delete", "get", "list", "watch", "update"] + - apiGroups: [""] + resources: ["persistentvolumesclaims"] + verbs: ["get", "list", "watch", "update"] + - apiGroups: [""] + resources: ["events"] + verbs: ["get", "list", "watch", "create", "update", "patch"] + - apiGroups: [""] + resources: ["nodes"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments"] + verbs: ["get", "list", "watch", "update"] + - apiGroups: ["storage.k8s.io"] + resources: ["storageclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments"] + verbs: ["get", "list", "watch", "update"] + - apiGroups: ["security.openshift.io"] + resourceNames: ["privileged"] + resources: ["securitycontextconstraints"] + verbs: ["use"] + {{- if hasKey .Values "podmon" }} + {{- if eq .Values.podmon.enabled true }} + - apiGroups: [""] + resources: ["pods"] + verbs: ["get", "list", "watch", "update", "delete"] + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "watch", "list", "delete", "update", "create"] + {{ end }} + {{ end }} + +--- + +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ .Release.Name }}-node +subjects: + - kind: ServiceAccount + name: {{ .Release.Name }}-node + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: {{ .Release.Name }}-node + apiGroup: rbac.authorization.k8s.io + +--- + +kind: DaemonSet +apiVersion: apps/v1 +metadata: + name: {{ .Release.Name }}-node + namespace: {{ .Release.Namespace }} +spec: + selector: + matchLabels: + app: {{ .Release.Name }}-node + template: + metadata: + labels: + app: {{ .Release.Name }}-node + {{- if .Values.podmon.enabled }} + driver.dellemc.com: dell-storage + {{- end }} + annotations: + kubectl.kubernetes.io/default-container: driver + spec: + {{ if .Values.node.nodeSelector }} + nodeSelector: + {{- toYaml .Values.node.nodeSelector | nindent 8 }} + {{ end }} + {{ if .Values.node.tolerations }} + tolerations: + {{- toYaml .Values.node.tolerations | nindent 6 }} + {{ end }} + serviceAccount: {{ .Release.Name }}-node + dnsPolicy: ClusterFirstWithHostNet + hostNetwork: true + hostIPC: true + containers: + {{- if hasKey .Values "podmon" }} + {{- if eq .Values.podmon.enabled true }} + - name: podmon + securityContext: + privileged: true + capabilities: + add: ["SYS_ADMIN"] + allowPrivilegeEscalation: true + image: {{ required "Must provide the podmon container image." .Values.images.podmon }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + args: + {{- toYaml .Values.podmon.node.args | nindent 12 }} + env: + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + - name: X_CSI_PRIVATE_MOUNT_DIR + value: {{ .Values.kubeletConfigDir }} + - name: MY_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: MY_POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: MY_POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + volumeMounts: + - name: kubelet-pods + mountPath: {{ .Values.kubeletConfigDir }}/pods + mountPropagation: "Bidirectional" + - name: driver-path + mountPath: {{ .Values.kubeletConfigDir }}/plugins/{{ .Values.driverName }} + mountPropagation: "Bidirectional" + - name: csi-path + mountPath: {{ .Values.kubeletConfigDir }}/plugins/kubernetes.io/csi + mountPropagation: "Bidirectional" + - name: dev + mountPath: /dev + - name: usr-bin + mountPath: /usr-bin + - name: var-run + mountPath: /var/run + - name: powerstore-config-params + mountPath: /powerstore-config-params + {{- end }} + {{- end }} + {{- if hasKey .Values "dev" }} + {{ if .Values.dev.enableTracing }}{{- include "pstore.tracing" . | nindent 8 }}{{ end }} + {{- end}} + - name: driver + securityContext: + privileged: true + capabilities: + add: ["SYS_ADMIN"] + allowPrivilegeEscalation: true + image: {{ required "Must provide the Powerstore driver image repository." .Values.images.driver }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + command: [ "/csi-powerstore" ] + env: + {{- if hasKey .Values "dev" }} + - name: ENABLE_TRACING + value: {{ .Values.dev.enableTracing | quote}} + {{ if .Values.dev.enableTracing }}{{- include "pstore.tracingenvvars" . | nindent 12 }}{{ end }} + {{- end}} + - name: CSI_ENDPOINT + value: unix://{{ .Values.kubeletConfigDir }}/plugins/{{ .Values.driverName }}/csi_sock + - name: X_CSI_MODE + value: node + - name: X_CSI_POWERSTORE_KUBE_NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + - name: X_CSI_POWERSTORE_NODE_NAME_PREFIX + value: {{ .Values.node.nodeNamePrefix }} + - name: X_CSI_POWERSTORE_NODE_ID_PATH + value: /node-id + - name: X_CSI_POWERSTORE_MAX_VOLUMES_PER_NODE + value: "{{ .Values.maxPowerstoreVolumesPerNode }}" + - name: X_CSI_POWERSTORE_NODE_CHROOT_PATH + value: /noderoot + - name: X_CSI_POWERSTORE_TMP_DIR + value: {{ .Values.kubeletConfigDir }}/plugins/{{ .Values.driverName }}/tmp + - name: X_CSI_DRIVER_NAME + value: {{ .Values.driverName }} + - name: X_CSI_FC_PORTS_FILTER_FILE_PATH + value: {{ .Values.nodeFCPortsFilterFile }} + {{- if eq .Values.connection.enableCHAP true }} + - name: X_CSI_POWERSTORE_ENABLE_CHAP + value: "true" + {{- else }} + - name: X_CSI_POWERSTORE_ENABLE_CHAP + value: "false" + {{- end }} + - name: X_CSI_POWERSTORE_CONFIG_PATH + value: /powerstore-config/config + - name: X_CSI_POWERSTORE_CONFIG_PARAMS_PATH + value: /powerstore-config-params/driver-config-params.yaml + - name: GOPOWERSTORE_DEBUG + value: "true" + {{- if hasKey .Values.node "healthMonitor" }} + {{- if eq .Values.node.healthMonitor.enabled true}} + - name: X_CSI_HEALTH_MONITOR_ENABLED + value: "{{ .Values.controller.healthMonitor.enabled }}" + {{- end }} + {{- end }} + {{- if hasKey .Values "podmon" }} + - name: X_CSI_PODMON_ENABLED + value: "{{ .Values.podmon.enabled }}" + {{- if eq .Values.podmon.enabled true }} + {{- range $key, $value := .Values.podmon.node.args }} + {{- if contains "--arrayConnectivityPollRate" $value }} + - name: X_CSI_PODMON_ARRAY_CONNECTIVITY_POLL_RATE + value: "{{ (split "=" $value)._1 }}" + {{- end }} + {{- end }} + {{- end }} + {{- end }} + - name: X_CSI_PODMON_API_PORT + value: "{{ .Values.podmonAPIPort }}" + volumeMounts: + - name: driver-path + mountPath: {{ .Values.kubeletConfigDir }}/plugins/{{ .Values.driverName }} + - name: csi-path + mountPath: {{ .Values.kubeletConfigDir }}/plugins/kubernetes.io/csi + mountPropagation: "Bidirectional" + - name: pods-path + mountPath: {{ .Values.kubeletConfigDir }}/pods + mountPropagation: "Bidirectional" + - name: dev + mountPath: /dev + - name: sys + mountPath: /sys + - name: run + mountPath: /run + - name: node-id + mountPath: /node-id + - name: etciscsi + mountPath: /etc/iscsi + - name: mpath + mountPath: /etc/multipath.conf + - name: noderoot + mountPath: /noderoot + - name: powerstore-config + mountPath: /powerstore-config + - name: powerstore-config-params + mountPath: /powerstore-config-params + - name: registrar + image: {{ required "Must provide the CSI node registrar container image." .Values.images.registrar }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + args: + - "--v=5" + - "--csi-address=$(ADDRESS)" + - --kubelet-registration-path={{ .Values.kubeletConfigDir }}/plugins/{{ .Values.driverName }}/csi_sock + env: + - name: ADDRESS + value: /csi/csi_sock + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + volumeMounts: + - name: registration-dir + mountPath: /registration + - name: driver-path + mountPath: /csi + volumes: + - name: registration-dir + hostPath: + path: {{ .Values.kubeletConfigDir }}/plugins_registry/ + type: DirectoryOrCreate + - name: driver-path + hostPath: + path: {{ .Values.kubeletConfigDir }}/plugins/{{ .Values.driverName }} + type: DirectoryOrCreate + - name: csi-path + hostPath: + path: {{ .Values.kubeletConfigDir }}/plugins/kubernetes.io/csi + - name: pods-path + hostPath: + path: {{ .Values.kubeletConfigDir }}/pods + type: Directory + - name: dev + hostPath: + path: /dev + type: Directory + - name: node-id + hostPath: + path: {{ required "Must provide the path to file with node identifier." .Values.node.nodeIDPath }} + type: File + - name: etciscsi + hostPath: + path: /etc/iscsi + type: DirectoryOrCreate + - name: mpath + hostPath: + path: /etc/multipath.conf + type: FileOrCreate + - name: noderoot + hostPath: + path: / + type: Directory + - name: sys + hostPath: + path: /sys + type: Directory + - name: run + hostPath: + path: /run + type: Directory + - name: powerstore-config-params + configMap: + name: {{ .Release.Name }}-config-params + - name: powerstore-config + secret: + secretName: {{ .Release.Name }}-config + {{- if hasKey .Values "podmon" }} + {{- if eq .Values.podmon.enabled true }} + - name: usr-bin + hostPath: + path: /usr/bin + type: Directory + - name: kubelet-pods + hostPath: + path: /var/lib/kubelet/pods + type: Directory + - name: var-run + hostPath: + path: /var/run + type: Directory + {{ end }} + {{ end }} diff --git a/charts/dell/csi-powerstore/2.11.1/values.yaml b/charts/dell/csi-powerstore/2.11.1/values.yaml new file mode 100644 index 0000000000..fc42b224fd --- /dev/null +++ b/charts/dell/csi-powerstore/2.11.1/values.yaml @@ -0,0 +1,350 @@ +# +# +# Copyright © 2020-2023 Dell Inc. or its subsidiaries. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# + +## K8S/DRIVER ATTRIBUTES +######################## + +# driverName: defines the name of driver +# Allowed values: string +# Default value: None +driverName: "csi-powerstore.dellemc.com" +# "version" is used to verify the values file matches driver version +# Not recommend to change +version: v2.11.1 + +# "images" defines every container images used for the driver and its sidecars. +# To use your own images, or a private registry, change the values here. +images: + # "driver" defines the container image, used for the driver container. + driver: dellemc/csi-powerstore:v2.11.1 + # CSI sidecars + attacher: registry.k8s.io/sig-storage/csi-attacher:v4.6.1 + provisioner: registry.k8s.io/sig-storage/csi-provisioner:v5.0.1 + snapshotter: registry.k8s.io/sig-storage/csi-snapshotter:v8.0.1 + resizer: registry.k8s.io/sig-storage/csi-resizer:v1.11.1 + registrar: registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.10.1 + healthmonitor: registry.k8s.io/sig-storage/csi-external-health-monitor-controller:v0.12.1 + + # CSM sidecars + replication: dellemc/dell-csi-replicator:v1.9.0 + vgsnapshotter: dellemc/csi-volumegroup-snapshotter:v1.6.0 + podmon: dellemc/podmon:v1.10.0 + metadataretriever: dellemc/csi-metadata-retriever:v1.8.0 + +# Specify kubelet config dir path. +# Ensure that the config.yaml file is present at this path. +# Default value: /var/lib/kubelet +kubeletConfigDir: /var/lib/kubelet + +# nodeFCPortsFilterFile: It is the name of the environment variable which store path to the file which +# provide list of WWPN which should be used by the driver for FC connection on this node +# If file not exist or empty or in invalid format, then the driver will use all available FC ports +# Allowed Values: string +# Default Value: None +# Example: +# content of the file: +# 21:00:00:29:ff:48:9f:6e,21:00:00:29:ff:48:9f:6e +nodeFCPortsFilterFile: /etc/fc-ports-filter + +# externalAccess: allows to specify additional entries for hostAccess of NFS volumes. Both single IP address and subnet are valid entries. +# Allowed Values: x.x.x.x/xx or x.x.x.x +# Default Value: None +externalAccess: + +# imagePullPolicy: Policy to determine if the image should be pulled prior to starting the container. +# Allowed values: +# Always: Always pull the image. +# IfNotPresent: Only pull the image if it does not already exist on the node. +# Never: Never pull the image. +# Default value: None +imagePullPolicy: IfNotPresent + +# maxPowerstoreVolumesPerNode: Specify default value for maximum number of volumes that controller can publish to the node. +# If value is zero CO SHALL decide how many volumes of this type can be published by the controller to the node. +# This limit is applicable to all the nodes in the cluster for which node label 'max-powerstore-volumes-per-node' is not set. +# Allowed values: n, where n >= 0 +# Default value: 0 +maxPowerstoreVolumesPerNode: 0 + +# nfsAcls: enables setting permissions on NFS mount directory +# This value acts as default value for NFS ACL (nfsAcls), if not specified for an array config in secret +# Permissions can be specified in two formats: +# 1) Unix mode (NFSv3) +# 2) NFSv4 ACLs (NFSv4) +# NFSv4 ACLs are supported on NFSv4 share only. +# Allowed values: +# 1) Unix mode: valid octal mode number +# Examples: "0777", "777", "0755" +# 2) NFSv4 acls: valid NFSv4 acls, seperated by comma +# Examples: "A::OWNER@:RWX,A::GROUP@:RWX", "A::OWNER@:rxtncy" +# Optional: true +# Default value: "0777" +nfsAcls: "0777" + +# podmonAPIPort: Defines the port to be used within the kubernetes cluster +# Allowed values: +# Any valid and free port. +# Default value: 8083 +podmonAPIPort: 8083 + +# controller: configure controller specific parameters +controller: + # controllerCount: defines the number of csi-powerstore controller pods to deploy to + # the Kubernetes release. + # Allowed values: n, where n > 0 + # Default value: None + controllerCount: 2 + + # volumeNamePrefix: defines a string prepended to each volume created by the CSI driver. + # Allowed values: string + # Default value: None + volumeNamePrefix: csivol + + # vgsnapshot: allows to configure volume-group-snapshot + # volume-group-snapshot CRDs must be installed before installing driver + vgsnapshot: + # enabled: Enable/Disable volume-group-snapshot feature + # Allowed values: + # true: enable volume-group-snapshot feature(install vg-snapshotter sidecar) + # false: disable volume-group-snapshot feature(do not install vg-snapshotter sidecar) + # Default value: false + enabled: false + + # snapshot: allows to enable/disable snapshot feature + # snapshot CRDs needs to be installed before enabling this feature + snapshot: + # enabled: Enable/Disable volume snapshot feature + # Allowed values: + # true: enable volume snapshot feature(install snapshotter sidecar) + # false: disable volume snapshot feature(do not install snapshotter sidecar) + # Default value: None + enabled: true + + # snapNamePrefix: Prefix to apply to the names of a created snapshots + # Allowed values: string + # Default value: None + snapNamePrefix: csisnap + # resizer: allows to enable/disable resizer feature + resizer: + # enabled: Enable/Disable volume expansion feature + # Allowed values: + # true: enable volume expansion feature(install resizer sidecar) + # false: disable volume expansion feature(do not install resizer sidecar) + # Default value: true + enabled: true + + healthMonitor: + # enabled: Enable/Disable health monitor of CSI volumes + # Allowed values: + # true: enable checking of health condition of CSI volumes + # false: disable checking of health condition of CSI volumes + # Default value: false + enabled: false + + # interval: Interval of monitoring volume health condition + # Allowed values: Number followed by unit (s,m,h) + # Examples: 60s, 5m, 1h + # Default value: 60s + interval: 60s + + # replication: allows to configure replication + # Replication CRDs must be installed before installing driver + replication: + # enabled: Enable/Disable replication feature + # Allowed values: + # true: enable replication feature(install dell-csi-replicator sidecar) + # false: disable replication feature(do not install dell-csi-replicator sidecar) + # Default value: false + enabled: false + + # replicationContextPrefix: prefix to use for naming of resources created by replication feature + # Allowed values: string + # Default value: powerstore + replicationContextPrefix: "powerstore" + + # replicationPrefix: prefix to prepend to storage classes parameters + # Allowed values: string + # Default value: replication.storage.dell.com + replicationPrefix: "replication.storage.dell.com" + + # nodeSelector: Define node selection constraints for controller pods. + # For the pod to be eligible to run on a node, the node must have each + # of the indicated key-value pairs as labels. + # Leave as blank to consider all nodes + # Allowed values: map of key-value pairs + # Default value: None + nodeSelector: + # Uncomment if nodes you wish to use have the node-role.kubernetes.io/master taint + # node-role.kubernetes.io/master + # Uncomment if nodes you wish to use have the node-role.kubernetes.io/control-plane taint + # node-role.kubernetes.io/control-plane + + # tolerations: Define tolerations for the controllers, if required. + # Leave as blank to install controller on worker nodes + # Default value: None + tolerations: + # Uncomment if nodes you wish to use have the node-role.kubernetes.io/master taint + # - key: "node-role.kubernetes.io/master" + # operator: "Exists" + # effect: "NoSchedule" + # Uncomment if nodes you wish to use have the node-role.kubernetes.io/control-plane taint + # tolerations: + # - key: "node-role.kubernetes.io/control-plane" + # operator: "Exists" + # effect: "NoSchedule" + +# node: configure node pod specific parameters +node: + # nodeNamePrefix: defines a string prepended to each node registered by the CSI driver. + # Allowed values: string + # Default value: None + nodeNamePrefix: csi-node + + # nodeIDPath: defines the path to file with node identifier (e.g. /etc/machine-id, /etc/hostname). + # Allowed values: string + # Default value: None + nodeIDPath: /etc/machine-id + + healthMonitor: + # enabled: Enable/Disable health monitor of CSI volumes- volume usage, volume condition + # Allowed values: + # true: enable checking of health condition of CSI volumes + # false: disable checking of health condition of CSI volumes + # Default value: None + enabled: false + + # nodeSelector: Define node selection constraints for node pods. + # For the pod to be eligible to run on a node, the node must have each + # of the indicated key-value pairs as labels. + # Leave as blank to consider all nodes + # Allowed values: map of key-value pairs + # Default value: None + nodeSelector: + # Uncomment if nodes you wish to use have the node-role.kubernetes.io/master taint + # node-role.kubernetes.io/master + # Uncomment if nodes you wish to use have the node-role.kubernetes.io/control-plane taint + # node-role.kubernetes.io/control-plane + + # tolerations: Define tolerations for the node pods, if required. + # Leave as blank to consider all worker nodes + # Default value: None + tolerations: + # Uncomment if nodes you wish to use have the node-role.kubernetes.io/master taint + # - key: "node-role.kubernetes.io/master" + # operator: "Exists" + # effect: "NoSchedule" + # Uncomment if nodes you wish to use have the node-role.kubernetes.io/control-plane taint + # tolerations: + # - key: "node-role.kubernetes.io/control-plane" + # operator: "Exists" + # effect: "NoSchedule" + + # Uncomment if CSM for Resiliency and CSI Driver pods monitor are enabled + # tolerations: + # - key: "offline.vxflexos.storage.dell.com" + # operator: "Exists" + # effect: "NoSchedule" + # - key: "vxflexos.podmon.storage.dell.com" + # operator: "Exists" + # effect: "NoSchedule" + # - key: "offline.unity.storage.dell.com" + # operator: "Exists" + # effect: "NoSchedule" + # - key: "unity.podmon.storage.dell.com" + # operator: "Exists" + # effect: "NoSchedule" + # - key: "offline.isilon.storage.dell.com" + # operator: "Exists" + # effect: "NoSchedule" + # - key: "isilon.podmon.storage.dell.com" + # operator: "Exists" + # effect: "NoSchedule" + # - key: "offline.powerstore.storage.dell.com" + # operator: "Exists" + # effect: "NoSchedule" + # - key: "powerstore.podmon.storage.dell.com" + # operator: "Exists" + # effect: "NoSchedule" + +## PLATFORM ATTRIBUTES +###################### + +# connection: allows to configure connection to storage array +connection: + # connection.enableCHAP: allows to enable CHAP for iSCSI connections + # CHAP password will be autogenerated by driver + # Allowed values: + # true : enable CHAP + # false: disable CHAP + # Default value: false + enableCHAP: false + +# CSI driver log level +# Allowed values: "error", "warn"/"warning", "info", "debug", "error" +# Default value: "debug" +logLevel: "debug" + +# CSI driver log format +# Allowed values: "TEXT" or "JSON" +# Default value: "JSON" +logFormat: "JSON" + +# Following modes are supported: None, File and ReadWriteOnceWithFSType +fsGroupPolicy: ReadWriteOnceWithFSType + +# Allows the controller to round off filesystem to 3Gi which is the minimum supported value +allowAutoRoundOffFilesystemSize: true + +# Storage Capacity Tracking +# Note: Capacity tracking is supported in kubernetes v1.24 and above, this feature will be automatically disabled in older versions. +storageCapacity: + # enabled : Enable/Disable storage capacity tracking + # Allowed values: + # true: enable storage capacity tracking + # false: disable storage capacity tracking + # Default value: true + enabled: true + # pollInterval : Configure how often external-provisioner polls the driver to detect changed capacity + # Allowed values: 1m,2m,3m,...,10m,...,60m etc + # Default value: 5m + pollInterval: 5m + +# Enable this feature only after contact support for additional information +podmon: + enabled: false + controller: + args: + - "--csisock=unix:/var/run/csi/csi.sock" + - "--labelvalue=csi-powerstore" + - "--arrayConnectivityPollRate=60" + - "--driverPath=csi-powerstore.dellemc.com" + - "--mode=controller" + - "--skipArrayConnectionValidation=false" + - "--driver-config-params=/powerstore-config-params/driver-config-params.yaml" + - "--driverPodLabelValue=dell-storage" + - "--ignoreVolumelessPods=false" + + node: + args: + - "--csisock=unix:/var/lib/kubelet/plugins/csi-powerstore.dellemc.com/csi_sock" + - "--labelvalue=csi-powerstore" + - "--arrayConnectivityPollRate=60" + - "--driverPath=csi-powerstore.dellemc.com" + - "--mode=node" + - "--leaderelection=false" + - "--driver-config-params=/powerstore-config-params/driver-config-params.yaml" + - "--driverPodLabelValue=dell-storage" + - "--ignoreVolumelessPods=false" diff --git a/charts/dell/csi-unity/2.11.1/Chart.yaml b/charts/dell/csi-unity/2.11.1/Chart.yaml new file mode 100644 index 0000000000..cf37985fb2 --- /dev/null +++ b/charts/dell/csi-unity/2.11.1/Chart.yaml @@ -0,0 +1,22 @@ +annotations: + catalog.cattle.io/certified: partner + catalog.cattle.io/display-name: Dell CSI Unity + catalog.cattle.io/kube-version: '>= 1.24.0' + catalog.cattle.io/release-name: unity +apiVersion: v2 +appVersion: 2.11.1 +description: 'Unity XT CSI (Container Storage Interface) driver Kubernetes integration. + This chart includes everything required to provision via CSI as well as a Unity + XT StorageClass. ' +icon: file://assets/icons/csi-unity.png +keywords: +- csi +- storage +kubeVersion: '>= 1.24.0' +maintainers: +- name: DellEMC +name: csi-unity +sources: +- https://github.com/dell/csi-unity +type: application +version: 2.11.1 diff --git a/charts/dell/csi-unity/2.11.1/app-readme.md b/charts/dell/csi-unity/2.11.1/app-readme.md new file mode 100644 index 0000000000..9c7fe7bd5d --- /dev/null +++ b/charts/dell/csi-unity/2.11.1/app-readme.md @@ -0,0 +1,93 @@ +The [CSI Driver for Unity XT](https://github.com/dell/csi-unity) is part of the CSM (Container Storage Modules) open-source suite of Kubernetes storage enablers for Dell products. CSI Driver for Unity XT is a Container Storage Interface (CSI) driver that provides support for provisioning persistent storage using Dell Unity XT storage array. + + +## Pre-Requisites +- Install Kubernetes (see [supported versions](https://dell.github.io/csm-docs/docs/csidriver/#features-and-capabilities)) +- Install Helm v3 (follow [steps](https://dell.github.io/csm-docs/docs/csidriver/installation/helm/unity/#install-helm-30)) +- Install sshpass +- Configure the pre-installation steps according to the protocols you are using: + - To use FC protocol, the host must be zoned with Unity XT array and Multipath needs to be configured + - To use iSCSI protocol, iSCSI initiator utils packages need to be installed and Multipath needs to be configured + - To use NFS protocol, NFS utility packages needs to be installed +- Enable mount propagation on container runtime that is being used +- In order to use the Kubernetes Volume Snapshot feature, ensure to deploy `Volume Snapshot CRDs` and `Volume Snapshot Controller` in the kubernetes cluster as a pre-requisite. Refer [here](https://dell.github.io/csm-docs/docs/csidriver/installation/helm/unity/#installation-example) for installation example of CRD's and default snapshot controller + +For more information, refer to the [documentation](https://dell.github.io/csm-docs/docs/csidriver/installation/helm/unity/#prerequisites) + +## Install CSI Driver for Unity XT + +1. Clone the [git repository](https://github.com/dell/csi-unity) that has the helm charts and install scripts +2. Create a namespace called `unity` +3. Collect information from the Unity XT Systems like Unique ArrayId, IP address, username, and password. Using the information, prepare `secrets.yaml`. Create the secrets. Samples available [here](https://github.com/dell/csi-unity/blob/main/samples/secret/secret.yaml) +>NOTE: For certificate validation of Unisphere REST API calls refer [here](https://dell.github.io/csm-docs/docs/csidriver/installation/helm/unity/#certificate-validation-for-unisphere-rest-api-calls). Otherwise, create an empty secret. Samples available [here](https://github.com/dell/csi-unity/tree/main/samples/secret/emptysecret.yaml) +4. Copy the `helm/csi-unity/values.yaml` into a file named `myvalues.yaml` in the same directory of csi-install.sh, to customize settings for installation +5. Edit `myvalues.yaml` to set the following parameters for your installation: + + The following table lists the primary configurable parameters of the Unity XT driver chart and their default values. More detailed information can be found in the [`values.yaml`](https://github.com/dell/csi-unity/blob/master/helm/csi-unity/values.yaml) file in this repository. + + | Parameter | Description | Required | Default | + | --------- | ----------- | -------- |-------- | + | version | helm version | true | - | + | logLevel | LogLevel is used to set the logging level of the driver | true | info | + | allowRWOMultiPodAccess | Flag to enable multiple pods to use the same PVC on the same node with RWO access mode. | false | false | + | kubeletConfigDir | Specify kubelet config dir path | Yes | /var/lib/kubelet | + | syncNodeInfoInterval | Time interval to add node info to the array. Default 15 minutes. The minimum value should be 1 minute. | false | 15 | + | maxUnityVolumesPerNode | Maximum number of volumes that controller can publish to the node. | false | 0 | + | certSecretCount | Represents the number of certificate secrets, which the user is going to create for SSL authentication. (unity-cert-0..unity-cert-n). The minimum value should be 1. | false | 1 | + | imagePullPolicy | The default pull policy is IfNotPresent which causes the Kubelet to skip pulling an image if it already exists. | Yes | IfNotPresent | + | podmon.enabled | service to monitor failing jobs and notify | false | - | + | podmon.image| pod man image name | false | - | + | tenantName | Tenant name added while adding host entry to the array | No | | + | fsGroupPolicy | Defines which FS Group policy mode to be used, Supported modes `None, File and ReadWriteOnceWithFSType` | No | "ReadWriteOnceWithFSType" | + | **controller** | Allows configuration of the controller-specific parameters.| - | - | + | controllerCount | Defines the number of csi-unity controller pods to deploy to the Kubernetes release| Yes | 2 | + | volumeNamePrefix | Defines a string prefix for the names of PersistentVolumes created | Yes | "k8s" | + | snapshot.enabled | Enable/Disable volume snapshot feature | Yes | true | + | snapshot.snapNamePrefix | Defines a string prefix for the names of the Snapshots created | Yes | "snapshot" | + | resizer.enabled | Enable/Disable volume expansion feature | Yes | true | + | nodeSelector | Define node selection constraints for pods of controller deployment | No | | + | tolerations | Define tolerations for the controller deployment, if required | No | | + | healthMonitor.enabled | Enable/Disable deployment of external health monitor sidecar for controller side volume health monitoring. | No | false | + | healthMonitor.interval | Interval of monitoring volume health condition. Allowed values: Number followed by unit (s,m,h) | No | 60s | + | ***node*** | Allows configuration of the node-specific parameters.| - | - | + | dnsPolicy | Define the DNS Policy of the Node service | Yes | ClusterFirstWithHostNet | + | healthMonitor.enabled | Enable/Disable health monitor of CSI volumes- volume usage, volume condition | No | false | + | nodeSelector | Define node selection constraints for pods of node deployment | No | | + | tolerations | Define tolerations for the node deployment, if required | No | | + + + **Note**: + + * User should provide all boolean values with double-quotes. This applies only for `myvalues.yaml`. Example: "true"/"false" + * controllerCount parameter value should be <= number of nodes in the kubernetes cluster else install script fails + +6. Run the `./csi-install.sh --namespace unity --values ./myvalues.yaml` command to proceed with the installation using bash script or you can also install the driver using standalone helm chart by running helm install command `helm install --dry-run --values --namespace `
+ `` - namespace of the driver installation
+ `` - unity in case of unity-creds and unity-certs-0 secrets
+ `` - Path of the helm directory
+ +7. Create storage classes from [samples](https://github.com/dell/csi-unity/tree/main/samples/storageclass) + + **Note**: + + * At least one storage class is required for one array + * In case you want to make updates to an existing storage class, ensure to delete it using the `kubectl delete storageclass ` command. Deleting a storage class has no impact on a running Pod with mounted PVCs. You cannot provision new PVCs until at least one storage class is newly created + +For full-length documentation, please visit Container Storage Modules documentation [page](https://dell.github.io/csm-docs/). + +## Support + +The CSI Driver for Dell Unity XT is fully supported by DELL. + +For all your support needs or to follow the latest ongoing discussions and updates, join our Slack group. Click [Here](http://del.ly/Slack_request) to request your invite. + +You can also interact with us on [GitHub](https://github.com/dell/csm) by creating a [GitHub Issue](https://github.com/dell/csm/issues). + +## Contributing + +We value all feedback and contributions. If you find any issues or want to contribute, please feel free to open an issue or file a PR. More details in [Contribution Guidelines](https://dell.github.io/csm-docs/docs/references/contributionguidelines/). + +## License + +This is open source software licensed using the Apache License 2.0. Please see [LICENSE](https://github.com/dell/csi-powerstore/blob/main/licenses/Apache.txt) for details. + diff --git a/charts/dell/csi-unity/2.11.1/templates/_helpers.tpl b/charts/dell/csi-unity/2.11.1/templates/_helpers.tpl new file mode 100644 index 0000000000..4031377c2a --- /dev/null +++ b/charts/dell/csi-unity/2.11.1/templates/_helpers.tpl @@ -0,0 +1,10 @@ +{{/* +Return true if storage capacity tracking is enabled and is supported based on k8s version +*/}} +{{- define "csi-unity.isStorageCapacitySupported" -}} +{{- if eq .Values.storageCapacity.enabled true -}} + {{- if and (eq .Capabilities.KubeVersion.Major "1") (ge (trimSuffix "+" .Capabilities.KubeVersion.Minor) "24") -}} + {{- true -}} + {{- end -}} +{{- end -}} +{{- end -}} diff --git a/charts/dell/csi-unity/2.11.1/templates/controller.yaml b/charts/dell/csi-unity/2.11.1/templates/controller.yaml new file mode 100644 index 0000000000..0c3e39edf2 --- /dev/null +++ b/charts/dell/csi-unity/2.11.1/templates/controller.yaml @@ -0,0 +1,328 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Release.Name }}-controller + namespace: {{ .Release.Namespace }} +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ .Release.Name }}-controller +rules: + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "watch", "list", "delete", "update", "create"] + - apiGroups: [""] + resources: ["events"] + verbs: ["list", "watch", "create", "update", "patch"] + - apiGroups: [""] + resources: ["nodes"] +{{- if .Values.podmon.enabled }} + verbs: ["get", "list", "watch", "patch"] +{{- else }} + verbs: ["get", "list", "watch"] +{{- end }} + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch", "create", "delete", "update","patch"] + - apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["get", "list", "create", "watch", "update"] + - apiGroups: ["storage.k8s.io"] + resources: ["storageclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments"] +{{- if .Values.podmon.enabled }} + verbs: ["get", "list", "watch", "update", "patch", "delete"] +{{- else }} + verbs: ["get", "list", "watch", "update","patch"] +{{- end }} + - apiGroups: ["storage.k8s.io"] + resources: ["csinodes"] + verbs: ["get", "list", "watch", "update"] + - apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments/status"] + verbs: ["patch"] + - apiGroups: ["csi.storage.k8s.io"] + resources: ["csinodeinfos"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["pods"] +{{- if .Values.podmon.enabled }} + verbs: ["get", "list", "watch", "update", "delete"] +{{- else }} + verbs: ["get", "list", "watch"] +{{- end }} +# below for snapshotter + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "list"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents"] + verbs: ["create", "get", "list", "watch", "update", "delete", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots/status"] + verbs: ["update"] + - apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments/status"] + verbs: ["patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots"] + verbs: ["get", "list", "watch", "update"] + - apiGroups: ["apiextensions.k8s.io"] + resources: ["customresourcedefinitions"] + verbs: ["create", "list", "watch", "delete"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents/status"] + verbs: ["update", "patch"] + # below for resizer + - apiGroups: [""] + resources: ["persistentvolumeclaims/status"] + verbs: ["update", "patch"] + # Permissions for CSIStorageCapacity + {{- if eq (include "csi-unity.isStorageCapacitySupported" .) "true" }} + - apiGroups: ["storage.k8s.io"] + resources: ["csistoragecapacities"] + verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] + - apiGroups: [""] + resources: ["pods"] + verbs: ["get"] + - apiGroups: ["apps"] + resources: ["replicasets"] + verbs: ["get"] + {{- end }} +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ .Release.Name }}-controller +subjects: + - kind: ServiceAccount + name: {{ .Release.Name }}-controller + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: {{ .Release.Name }}-controller + apiGroup: rbac.authorization.k8s.io +--- +{{ $releaseName := .Release.Name }} +kind: Deployment +apiVersion: apps/v1 +metadata: + name: {{ .Release.Name }}-controller + namespace: {{ .Release.Namespace }} +spec: + {{- if lt (.Values.controller.controllerCount | toString | atoi ) 1 -}} + {{- fail "value for .Values.controller.controllerCount should be atleast 1" }} + {{- else }} + replicas: {{ required "Must provide the number of controller instances to create." .Values.controller.controllerCount }} + {{- end }} + selector: + matchLabels: + app: {{ .Release.Name }}-controller + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: "driver" + labels: + app: {{ .Release.Name }}-controller + spec: + serviceAccountName: {{ .Release.Name }}-controller + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app + operator: In + values: + - {{ .Release.Name }}-controller + topologyKey: "kubernetes.io/hostname" + {{- if .Values.controller.nodeSelector }} + nodeSelector: + {{- toYaml .Values.controller.nodeSelector | nindent 8 }} + {{- end }} + {{- if .Values.controller.tolerations }} + tolerations: + {{- toYaml .Values.controller.tolerations | nindent 6 }} + {{- end }} + containers: +{{- if .Values.podmon.enabled }} + - name: podmon + imagePullPolicy: {{ .Values.imagePullPolicy }} + image: {{ required "Must provide the podmon container image." .Values.images.podmon }} + args: + {{- toYaml .Values.podmon.controller.args | nindent 12 }} + env: + - name: MY_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: MY_POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: MY_POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + volumeMounts: + - name: socket-dir + mountPath: /var/run/csi + - name: unity-config + mountPath: /unity-config +{{- end }} + - name: attacher + image: {{ required "Must provide the CSI attacher container image." .Values.images.attacher }} + args: + - "--csi-address=$(ADDRESS)" + - "--v=5" + - "--leader-election" + env: + - name: ADDRESS + value: /var/run/csi/csi.sock + volumeMounts: + - name: socket-dir + mountPath: /var/run/csi + - name: provisioner + image: {{ required "Must provide the CSI provisioner container image." .Values.images.provisioner }} + args: + - "--csi-address=$(ADDRESS)" + - "--volume-name-prefix={{ required "Must provide a Volume Name Prefix." .Values.controller.volumeNamePrefix }}" + - "--volume-name-uuid-length=10" + - "--timeout=180s" + - "--worker-threads=6" + - "--v=5" + - "--feature-gates=Topology=true" + - "--strict-topology=true" + - "--leader-election" + - "--leader-election-namespace={{ .Release.Namespace }}" + - "--default-fstype={{ .Values.defaultFsType | default "ext4" }}" + - "--enable-capacity={{ (include "csi-unity.isStorageCapacitySupported" .) | default false }}" + - "--capacity-ownerref-level=2" + - "--capacity-poll-interval={{ .Values.storageCapacity.pollInterval | default "5m" }}" + env: + - name: ADDRESS + value: /var/run/csi/csi.sock + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + volumeMounts: + - name: socket-dir + mountPath: /var/run/csi + {{- if hasKey .Values.controller "snapshot" }} + {{- if eq .Values.controller.snapshot.enabled true }} + - name: snapshotter + image: {{ required "Must provide the CSI snapshotter container image. " .Values.images.snapshotter }} + args: + - "--csi-address=$(ADDRESS)" + - "--snapshot-name-prefix={{ required "Must privided a Snapshot Name Prefix" .Values.controller.snapshot.snapNamePrefix }}" + - "--snapshot-name-uuid-length=10" + - "--timeout=360s" + - "--v=5" + - "--leader-election" + env: + - name: ADDRESS + value: /var/run/csi/csi.sock + volumeMounts: + - name: socket-dir + mountPath: /var/run/csi + {{- end}} + {{- end}} + {{- if hasKey .Values.controller "resizer" }} + {{- if eq .Values.controller.resizer.enabled true }} + - name: resizer + image: {{ required "Must provide the CSI resizer container image." .Values.images.resizer }} + args: + - "--csi-address=$(ADDRESS)" + - "--v=5" + - "--leader-election" + env: + - name: ADDRESS + value: /var/run/csi/csi.sock + volumeMounts: + - name: socket-dir + mountPath: /var/run/csi + {{ end }} + {{ end }} + {{- if hasKey .Values.controller "healthMonitor" }} + {{- if eq .Values.controller.healthMonitor.enabled true }} + - name: csi-external-health-monitor-controller + image: {{ required "Must provide the CSI external health monitor image." .Values.images.healthmonitor }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + args: + - "--v=5" + - "--csi-address=$(ADDRESS)" + - "--leader-election" + - "--http-endpoint=:8080" + - "--enable-node-watcher=true" + - "--monitor-interval={{ .Values.controller.healthMonitor.interval | default "60s" }}" + - "--timeout=180s" + env: + - name: ADDRESS + value: /var/run/csi/csi.sock + volumeMounts: + - name: socket-dir + mountPath: /var/run/csi + {{- end }} + {{- end }} + - name: driver + image: "{{ required "Must provide the driver image repository." .Values.images.driver }}" + args: + - "--driver-name=csi-unity.dellemc.com" + - "--driver-config=/unity-config/driver-config-params.yaml" + - "--driver-secret=/unity-secret/config" + imagePullPolicy: {{ .Values.imagePullPolicy }} + env: + - name: CSI_ENDPOINT + value: /var/run/csi/csi.sock + - name: X_CSI_MODE + value: controller + - name: X_CSI_UNITY_AUTOPROBE + value: "true" + - name: SSL_CERT_DIR + value: /certs + {{- if hasKey .Values.controller "healthMonitor" }} + {{- if eq .Values.controller.healthMonitor.enabled true }} + - name: X_CSI_HEALTH_MONITOR_ENABLED + value: "{{ .Values.controller.healthMonitor.enabled }}" + {{- end }} + {{- end }} + volumeMounts: + - name: socket-dir + mountPath: /var/run/csi + - name: certs + mountPath: /certs + readOnly: true + - name: unity-config + mountPath: /unity-config + - name: unity-secret + mountPath: /unity-secret + volumes: + - name: certs + projected: + sources: +{{- range $i, $e := until (int .Values.certSecretCount ) }} + - secret: + name: {{ print $releaseName "-certs-" $e }} + items: + - key: cert-{{ $e }} + path: cert-{{ $e }} +{{- end }} + - name: socket-dir + emptyDir: + - name: unity-config + configMap: + name: {{ .Release.Name }}-config-params + - name: unity-secret + secret: + secretName: {{ .Release.Name }}-creds diff --git a/charts/dell/csi-unity/2.11.1/templates/csidriver.yaml b/charts/dell/csi-unity/2.11.1/templates/csidriver.yaml new file mode 100644 index 0000000000..80f594e8ca --- /dev/null +++ b/charts/dell/csi-unity/2.11.1/templates/csidriver.yaml @@ -0,0 +1,12 @@ +apiVersion: storage.k8s.io/v1 +kind: CSIDriver +metadata: + name: csi-unity.dellemc.com +spec: + storageCapacity: {{ (include "csi-unity.isStorageCapacitySupported" .) | default false }} + attachRequired: true + podInfoOnMount: true + volumeLifecycleModes: + - Persistent + - Ephemeral + fsGroupPolicy: {{ .Values.fsGroupPolicy }} diff --git a/charts/dell/csi-unity/2.11.1/templates/driver-config-params.yaml b/charts/dell/csi-unity/2.11.1/templates/driver-config-params.yaml new file mode 100644 index 0000000000..2bbf894829 --- /dev/null +++ b/charts/dell/csi-unity/2.11.1/templates/driver-config-params.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-config-params + namespace: {{ .Release.Namespace }} +data: + driver-config-params.yaml: | + CSI_LOG_LEVEL: "{{ .Values.logLevel }}" + ALLOW_RWO_MULTIPOD_ACCESS: "{{ .Values.allowRWOMultiPodAccess }}" + MAX_UNITY_VOLUMES_PER_NODE: "{{ .Values.maxUnityVolumesPerNode }}" + SYNC_NODE_INFO_TIME_INTERVAL: "{{ .Values.syncNodeInfoInterval }}" + TENANT_NAME: "{{ .Values.tenantName }}" + {{ if .Values.podmon.enabled }} + PODMON_CONTROLLER_LOG_LEVEL: "{{ .Values.logLevel }}" + PODMON_CONTROLLER_LOG_FORMAT: "TEXT" + PODMON_NODE_LOG_LEVEL: "{{ .Values.logLevel }}" + PODMON_NODE_LOG_FORMAT: "TEXT" + {{ end }} diff --git a/charts/dell/csi-unity/2.11.1/templates/node.yaml b/charts/dell/csi-unity/2.11.1/templates/node.yaml new file mode 100644 index 0000000000..8788b79a33 --- /dev/null +++ b/charts/dell/csi-unity/2.11.1/templates/node.yaml @@ -0,0 +1,283 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Release.Name }}-node + namespace: {{ .Release.Namespace }} +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ .Release.Name }}-node +rules: + - apiGroups: [ "" ] + resources: [ "persistentvolumes" ] + verbs: [ "create", "delete", "get", "list", "watch", "update" ] + - apiGroups: [ "" ] + resources: [ "persistentvolumesclaims" ] + verbs: [ "get", "list", "watch", "update" ] + - apiGroups: [ "" ] + resources: [ "events" ] + verbs: [ "get", "list", "watch", "create", "update", "patch" ] + - apiGroups: [ "" ] + resources: [ "nodes" ] + verbs: [ "get", "list", "watch", "update", "patch" ] + - apiGroups: [ "storage.k8s.io" ] + resources: [ "volumeattachments" ] + verbs: [ "get", "list", "watch", "update" ] + - apiGroups: [ "storage.k8s.io" ] + resources: [ "storageclasses" ] + verbs: [ "get", "list", "watch" ] + - apiGroups: [ "storage.k8s.io" ] + resources: [ "volumeattachments" ] + verbs: [ "get", "list", "watch", "update" ] + - apiGroups: [ "security.openshift.io" ] + resourceNames: [ "privileged" ] + resources: [ "securitycontextconstraints" ] + verbs: [ "use" ] +{{- if .Values.podmon.enabled }} + - apiGroups: [ "" ] + resources: [ "pods" ] + verbs: [ "get", "list", "watch", "update", "delete" ] + - apiGroups: [ "coordination.k8s.io" ] + resources: [ "leases" ] + verbs: [ "get", "watch", "list", "delete", "update", "create" ] +{{- end }} +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ .Release.Name }}-node +subjects: + - kind: ServiceAccount + name: {{ .Release.Name }}-node + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: {{ .Release.Name }}-node + apiGroup: rbac.authorization.k8s.io +--- +{{ $releaseName := .Release.Name }} +kind: DaemonSet +apiVersion: apps/v1 +metadata: + name: {{ .Release.Name }}-node + namespace: {{ .Release.Namespace }} +spec: + updateStrategy: + type: RollingUpdate + selector: + matchLabels: + app: {{ .Release.Name }}-node + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: "driver" + labels: + app: {{ .Release.Name }}-node +{{- if .Values.podmon.enabled }} + driver.dellemc.com: dell-storage +{{- end }} + spec: + serviceAccountName: {{ .Release.Name }}-node + {{- if .Values.node.nodeSelector }} + nodeSelector: + {{- toYaml .Values.node.nodeSelector | nindent 8 }} + {{- end }} + {{- if .Values.node.tolerations }} + tolerations: + {{- toYaml .Values.node.tolerations | nindent 8 }} + {{- end }} + hostIPC: true + hostNetwork: true + dnsPolicy: {{ .Values.node.dnsPolicy }} + containers: +{{- if .Values.podmon.enabled }} + - name: podmon + securityContext: + privileged: true + capabilities: + add: ["SYS_ADMIN"] + allowPrivilegeEscalation: true + imagePullPolicy: {{ .Values.imagePullPolicy }} + image: {{ required "Must provide the podmon container image." .Values.images.podmon }} + args: + {{- toYaml .Values.podmon.node.args | nindent 12 }} + env: + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + - name: X_CSI_PRIVATE_MOUNT_DIR + value: "{{ .Values.kubeletConfigDir }}/plugins/unity.emc.dell.com/disks" + - name: MY_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: MY_POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: MY_POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + volumeMounts: + - name: kubelet-pods + mountPath: {{ .Values.kubeletConfigDir }}/pods + mountPropagation: "Bidirectional" + - name: driver-path + mountPath: {{ .Values.kubeletConfigDir }}/plugins/unity.emc.dell.com + mountPropagation: "Bidirectional" + - name: volumedevices-path + mountPath: {{ .Values.kubeletConfigDir }}/plugins/kubernetes.io/csi + mountPropagation: "Bidirectional" + - name: dev + mountPath: /dev + - name: usr-bin + mountPath: /usr-bin + - name: var-run + mountPath: /var/run + - name: unity-config + mountPath: /unity-config +{{- end }} + - name: driver + securityContext: + privileged: true + capabilities: + add: ["SYS_ADMIN"] + allowPrivilegeEscalation: true + image: "{{ required "Must provide the driver image repository." .Values.images.driver }}" + args: + - "--driver-name=csi-unity.dellemc.com" + - "--driver-config=/unity-config/driver-config-params.yaml" + - "--driver-secret=/unity-secret/config" + imagePullPolicy: {{ .Values.imagePullPolicy }} + env: + - name: CSI_ENDPOINT + value: {{ .Values.kubeletConfigDir }}/plugins/unity.emc.dell.com/csi_sock + - name: X_CSI_MODE + value: node + - name: X_CSI_UNITY_AUTOPROBE + value: "true" + - name: X_CSI_UNITY_ALLOW_MULTI_POD_ACCESS + value: {{ .Values.allowRWOMultiPodAccess | default "false" | lower | quote }} + - name: X_CSI_ALLOWED_NETWORKS + value: "{{ .Values.allowedNetworks }}" + - name: X_CSI_PRIVATE_MOUNT_DIR + value: "{{ .Values.kubeletConfigDir }}/plugins/unity.emc.dell.com/disks" + - name: X_CSI_EPHEMERAL_STAGING_PATH + value: "{{ .Values.kubeletConfigDir }}/plugins/kubernetes.io/csi/pv/" + - name: X_CSI_ISCSI_CHROOT + value: {{ .Values.ISCSIChroot | default "/noderoot" }} + - name: X_CSI_UNITY_NODENAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + - name: X_CSI_UNITY_NODENAME_PREFIX + value: {{ .Values.nodeNamePrefix }} + - name: SSL_CERT_DIR + value: /certs + - name: X_CSI_UNITY_SYNC_NODEINFO_INTERVAL + value: {{ .Values.syncNodeInfoInterval | default "15" | quote }} + {{- if hasKey .Values.node "healthMonitor" }} + {{- if eq .Values.node.healthMonitor.enabled true }} + - name: X_CSI_HEALTH_MONITOR_ENABLED + value: "{{ .Values.node.healthMonitor.enabled }}" + {{- end }} + {{- end }} + volumeMounts: + - name: driver-path + mountPath: {{ .Values.kubeletConfigDir }}/plugins/unity.emc.dell.com + - name: volumedevices-path + mountPath: {{ .Values.kubeletConfigDir }}/plugins/kubernetes.io/csi + mountPropagation: "Bidirectional" + - name: pods-path + mountPath: {{ .Values.kubeletConfigDir }}/pods + mountPropagation: "Bidirectional" + - name: dev + mountPath: /dev + - name: noderoot + mountPath: /noderoot + - name: certs + mountPath: /certs + readOnly: true + - name: unity-config + mountPath: /unity-config + - name: unity-secret + mountPath: /unity-secret + - name: registrar + image: {{ required "Must provide the CSI registrar container image." .Values.images.registrar }} + args: + - "--v=5" + - "--csi-address=$(ADDRESS)" + - --kubelet-registration-path={{ .Values.kubeletConfigDir }}/plugins/unity.emc.dell.com/csi_sock + env: + - name: ADDRESS + value: /csi/csi_sock + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + volumeMounts: + - name: registration-dir + mountPath: /registration + - name: driver-path + mountPath: /csi + volumes: + - name: registration-dir + hostPath: + path: {{ .Values.kubeletConfigDir }}/plugins_registry/ + type: DirectoryOrCreate + - name: driver-path + hostPath: + path: {{ .Values.kubeletConfigDir }}/plugins/unity.emc.dell.com + type: DirectoryOrCreate + - name: volumedevices-path + hostPath: + path: {{ .Values.kubeletConfigDir }}/plugins/kubernetes.io/csi + type: DirectoryOrCreate + - name: pods-path + hostPath: + path: {{ .Values.kubeletConfigDir }}/pods + type: Directory + - name: dev + hostPath: + path: /dev + type: Directory + - name: noderoot + hostPath: + path: / + type: Directory + - name: certs + projected: + sources: +{{- range $i, $e := until (int .Values.certSecretCount ) }} + - secret: + name: {{ print $releaseName "-certs-" $e }} + items: + - key: cert-{{ $e }} + path: cert-{{ $e }} +{{- end }} + - name: unity-config + configMap: + name: {{ .Release.Name }}-config-params + - name: unity-secret + secret: + secretName: {{ .Release.Name }}-creds +{{- if .Values.podmon.enabled }} + - name: usr-bin + hostPath: + path: /usr/bin + type: Directory + - name: kubelet-pods + hostPath: + path: {{ .Values.kubeletConfigDir }}/pods + type: Directory + - name: var-run + hostPath: + path: /var/run + type: Directory +{{- end }} diff --git a/charts/dell/csi-unity/2.11.1/values.yaml b/charts/dell/csi-unity/2.11.1/values.yaml new file mode 100644 index 0000000000..5923fa3559 --- /dev/null +++ b/charts/dell/csi-unity/2.11.1/values.yaml @@ -0,0 +1,273 @@ +## K8S/DRIVER ATTRIBUTES +######################## + +# version: version of this values file +# Note: Do not change this value +# Examples : "v2.9.0" , "nightly" +version: "v2.11.1" + +images: + # "driver" defines the container image, used for the driver container. + driver: dellemc/csi-unity:v2.11.1 + # CSI sidecars + attacher: registry.k8s.io/sig-storage/csi-attacher:v4.6.1 + provisioner: registry.k8s.io/sig-storage/csi-provisioner:v5.0.1 + snapshotter: registry.k8s.io/sig-storage/csi-snapshotter:v8.0.1 + resizer: registry.k8s.io/sig-storage/csi-resizer:v1.11.1 + registrar: registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.10.1 + healthmonitor: registry.k8s.io/sig-storage/csi-external-health-monitor-controller:v0.12.1 + + # CSM sidecars + podmon: dellemc/podmon:v1.10.0 + +# LogLevel is used to set the logging level of the driver. +# Allowed values: "error", "warn"/"warning", "info", "debug" +# Default value: "info" +logLevel: "info" + +# certSecretCount: Represents number of certificate secrets, which user is going to create for +# ssl authentication. (unity-cert-0..unity-cert-n) +# Allowed values: n, where n > 0 +# Default value: None +certSecretCount: 1 + +# allowedNetworks: Custom networks for Unity export +# Specify list of networks which can be used for NFS I/O traffic; CIDR format should be used. +# Allowed values: list of one or more networks (comma separated) +# Default value: None +# Examples: 192.168.1.0/24, 192.168.100.0/22 +allowedNetworks: + +# imagePullPolicy: Policy to determine if the image should be pulled prior to starting the container. +# Allowed values: +# Always: Always pull the image. +# IfNotPresent: Only pull the image if it does not already exist on the node. +# Never: Never pull the image. +# Default value: IfNotPresent +imagePullPolicy: Always + +# Specify kubelet config dir path. +# Ensure that the config.yaml file is present at this path. +# Default value: /var/lib/kubelet +kubeletConfigDir: /var/lib/kubelet + +# fsGroupPolicy: Defines if the underlying volume supports changing ownership and permission of the volume before being mounted. +# Allowed values: +# ReadWriteOnceWithFSType: supports volume ownership and permissions change only if the fsType is defined +# and the volume's accessModes contains ReadWriteOnce. +# File: kubernetes may use fsGroup to change permissions and ownership of the volume +# to match user requested fsGroup in the pod's security policy regardless of fstype or access mode. +# None: volumes will be mounted with no modifications. +# Default value: ReadWriteOnceWithFSType +fsGroupPolicy: ReadWriteOnceWithFSType + +# To set nodeSelectors and tolerations for controller. +# controller: configure controller pod specific parameters +controller: + # controllerCount: defines the number of csi-unity controller pods to deploy to + # the Kubernetes release. + # Allowed values: n, where n > 0 + # Default value: None + controllerCount: 2 + + # volumeNamePrefix: Prefix of PersistentVolume names created + # Allowed values: string + # Default value: None + volumeNamePrefix: csivol + + snapshot: + # enabled: Enable/Disable volume snapshot feature + # Allowed values: + # true: enable volume snapshot feature(install snapshotter sidecar) + # false: disable volume snapshot feature(do not install snapshotter sidecar) + # Default value: None + enabled: true + + # snapNamePrefix: Prefix to apply to the names of a created snapshots + # Allowed values: string + # Default value: None + snapNamePrefix: csi-snap + + resizer: + # enabled: Enable/Disable volume expansion feature + # Allowed values: + # true: enable volume expansion feature(install resizer sidecar) + # false: disable volume snapshot feature(do not install resizer sidecar) + # Default value: None + enabled: true + + # nodeSelector: Define node selection constraints for controller pods. + # For the pod to be eligible to run on a node, the node must have each + # of the indicated key-value pairs as labels. + # Leave as blank to consider all nodes + # Allowed values: map of key-value pairs + # Default value: None + nodeSelector: + # Uncomment if nodes you wish to use have the node-role.kubernetes.io/master taint + # node-role.kubernetes.io/master: "" + # Uncomment if nodes you wish to use have the node-role.kubernetes.io/control-plane taint + # node-role.kubernetes.io/control-plane: "" + + # tolerations: Define tolerations for the controllers, if required. + # Leave as blank to install controller on worker nodes + # Default value: None + tolerations: + # Uncomment if nodes you wish to use have the node-role.kubernetes.io/master taint + # - key: "node-role.kubernetes.io/master" + # operator: "Exists" + # effect: "NoExecute" + # Uncomment if nodes you wish to use have the node-role.kubernetes.io/control-plane taint + # - key: "node-role.kubernetes.io/control-plane" + # operator: "Exists" + # effect: "NoSchedule" + + healthMonitor: + # enabled: Enable/Disable health monitor of CSI volumes- volume state, volume condition + # Allowed values: + # true: enable checking of health condition of CSI volumes + # false: disable checking of health condition of CSI volumes + # Default value: None + enabled: false + + # interval: Interval of monitoring volume health condition + # Allowed values: Number followed by unit of time (s,m,h) + # Default value: 60s + interval: 60s + +# node: configure node pod specific parameters +node: + # dnsPolicy : Define the DNS Policy of the Node service. + # ClusterFirstWithHostNet is the recommended and default DNS policy for the driver. + # Prior to v1.6 of the driver, the default DNS policy was ClusterFirst. + # In certain scenarios, users might need to change the default dnsPolicy. + # Default value: None + dnsPolicy: "ClusterFirstWithHostNet" + + healthMonitor: + # enabled: Enable/Disable health monitor of CSI Volumes - volume usage + # Allowed values: + # true: enable checking of health condition of CSI volumes + # false: disable checking of health condition of CSI volumes + # Default value: None + enabled: false + + # nodeSelector: Define node selection constraints for node pods. + # For the pod to be eligible to run on a node, the node must have each + # of the indicated key-value pairs as labels. + # Leave as blank to consider all nodes + # Allowed values: map of key-value pairs + # Default value: None + nodeSelector: + # Uncomment if nodes you wish to use have the node-role.kubernetes.io/master taint + # node-role.kubernetes.io/master: "" + # Uncomment if nodes you wish to use have the node-role.kubernetes.io/control-plane taint + # node-role.kubernetes.io/control-plane: "" + + # tolerations: Define tolerations for the node daemonset, if required. + # Default value: None + tolerations: + # Uncomment if nodes you wish to use have the node-role.kubernetes.io/master taint + # - key: "node-role.kubernetes.io/master" + # operator: "Exists" + # effect: "NoExecute" + # Uncomment if nodes you wish to use have the node-role.kubernetes.io/control-plane taint + # - key: "node-role.kubernetes.io/control-plane" + # operator: "Exists" + # effect: "NoExecute" + # - key: "node.kubernetes.io/memory-pressure" + # operator: "Exists" + # effect: "NoExecute" + # - key: "node.kubernetes.io/disk-pressure" + # operator: "Exists" + # effect: "NoExecute" + # - key: "node.kubernetes.io/network-unavailable" + # operator: "Exists" + # effect: "NoExecute" + # Uncomment if CSM for Resiliency and CSI Driver pods monitor are enabled + # - key: "offline.vxflexos.storage.dell.com" + # operator: "Exists" + # effect: "NoSchedule" + # - key: "vxflexos.podmon.storage.dell.com" + # operator: "Exists" + # effect: "NoSchedule" + # - key: "offline.unity.storage.dell.com" + # operator: "Exists" + # effect: "NoSchedule" + # - key: "unity.podmon.storage.dell.com" + # operator: "Exists" + # effect: "NoSchedule" + # - key: "offline.isilon.storage.dell.com" + # operator: "Exists" + # effect: "NoSchedule" + # - key: "isilon.podmon.storage.dell.com" + # operator: "Exists" + # effect: "NoSchedule" + +# CSM module attributes +# service to monitor failing jobs and notify +podmon: + # enabled - flag to enable or disable podmon + # allowed values : boolean + # defaule value : None + # Examples : true , false + enabled: false + controller: + args: + - "--csisock=unix:/var/run/csi/csi.sock" + - "--labelvalue=csi-unity" + - "--driverPath=csi-unity.dellemc.com" + - "--mode=controller" + - "--skipArrayConnectionValidation=false" + - "--driver-config-params=/unity-config/driver-config-params.yaml" + - "--driverPodLabelValue=dell-storage" + - "--ignoreVolumelessPods=false" + node: + args: + - "--csisock=unix:/var/lib/kubelet/plugins/unity.emc.dell.com/csi_sock" + - "--labelvalue=csi-unity" + - "--driverPath=csi-unity.dellemc.com" + - "--mode=node" + - "--leaderelection=false" + - "--driver-config-params=/unity-config/driver-config-params.yaml" + - "--driverPodLabelValue=dell-storage" + - "--ignoreVolumelessPods=false" + +### The below parameters have been discontinued for configuration from secret.yaml and will have to be configured only in values.yaml + +# syncNodeInfoInterval - Time interval to add node info to array. Default 15 minutes. Minimum value should be 1. +# Allowed values: integer +# Default value: 15 +# Examples : 0 , 2 +syncNodeInfoInterval: 15 + +# allowRWOMultiPodAccess - Flag to enable sharing of volumes across multiple pods within the same node in RWO access mode. +# Allowed values: boolean +# Default value: "false" +# Examples : "true" , "false" +allowRWOMultiPodAccess: "false" + +# maxUnityVolumesPerNode - Maximum number of volumes that controller can publish to the node. +# Allowed values: integer +# Default value: 0 +# Examples : 0 , 1 +maxUnityVolumesPerNode: 0 + +# tenantName - Tenant name that need to added while adding host entry to the array. +# Allowed values: string +# Default value: "" +# Examples : "tenant2" , "tenant3" +tenantName: "" + +# Storage Capacity Tracking +# Note: Capacity tracking is supported in kubernetes v1.24 and above, this feature will be automatically disabled in older versions. +storageCapacity: + # enabled : Enable/Disable storage capacity tracking + # Allowed values: + # true: enable storage capacity tracking + # false: disable storage capacity tracking + # Default value: true + enabled: true + # pollInterval : Configure how often external-provisioner polls the driver to detect changed capacity + # Allowed values: 1m,2m,3m,...,10m,...,60m etc + # Default value: 5m + pollInterval: 5m diff --git a/charts/external-secrets/external-secrets/0.10.4/Chart.lock b/charts/external-secrets/external-secrets/0.10.4/Chart.lock new file mode 100644 index 0000000000..f9abae8c12 --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/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-09-20T12:57:07.63511+02:00" diff --git a/charts/external-secrets/external-secrets/0.10.4/Chart.yaml b/charts/external-secrets/external-secrets/0.10.4/Chart.yaml new file mode 100644 index 0000000000..ffe33d8e17 --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/Chart.yaml @@ -0,0 +1,25 @@ +annotations: + catalog.cattle.io/certified: partner + catalog.cattle.io/display-name: External Secrets Operator + catalog.cattle.io/kube-version: '>= 1.19.0-0' + catalog.cattle.io/release-name: external-secrets +apiVersion: v2 +appVersion: v0.10.4 +dependencies: +- condition: bitwarden-sdk-server.enabled + name: bitwarden-sdk-server + repository: file://./charts/bitwarden-sdk-server + version: v0.3.1 +description: External secret management for Kubernetes +home: https://github.com/external-secrets/external-secrets +icon: file://assets/icons/external-secrets.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.4 diff --git a/charts/external-secrets/external-secrets/0.10.4/README.md b/charts/external-secrets/external-secrets/0.10.4/README.md new file mode 100644 index 0000000000..89f7b57bc6 --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/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.4](https://img.shields.io/badge/Version-0.10.4-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 | `"oci.external-secrets.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 | `"oci.external-secrets.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 | `"oci.external-secrets.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/charts/external-secrets/external-secrets/0.10.4/app-readme.md b/charts/external-secrets/external-secrets/0.10.4/app-readme.md new file mode 100644 index 0000000000..2a28bc3992 --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/app-readme.md @@ -0,0 +1,7 @@ +**External Secrets Operator** is a Kubernetes operator that integrates external secret management systems like [AWS Secrets Manager](https://aws.amazon.com/secrets-manager/), [HashiCorp Vault](https://www.vaultproject.io/), [Google Secrets Manager](https://cloud.google.com/secret-manager), [Azure Key Vault](https://azure.microsoft.com/en-us/services/key-vault/) and many more. +The operator reads information from external APIs and automatically injects the values into a [Kubernetes Secret](https://kubernetes.io/docs/concepts/configuration/secret/). + +### What is the goal of External Secrets Operator? + +The goal of External Secrets Operator is to synchronize secrets from external APIs into Kubernetes. ESO is a collection of custom API resources - `ExternalSecret`, `SecretStore` and `ClusterSecretStore` that provide a user-friendly abstraction for the external API that stores and manages the lifecycle of the secrets for you. + diff --git a/charts/external-secrets/external-secrets/0.10.4/charts/bitwarden-sdk-server/.helmignore b/charts/external-secrets/external-secrets/0.10.4/charts/bitwarden-sdk-server/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/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/charts/external-secrets/external-secrets/0.10.4/charts/bitwarden-sdk-server/Chart.yaml b/charts/external-secrets/external-secrets/0.10.4/charts/bitwarden-sdk-server/Chart.yaml new file mode 100644 index 0000000000..64d6f38534 --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/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/charts/external-secrets/external-secrets/0.10.4/charts/bitwarden-sdk-server/templates/NOTES.txt b/charts/external-secrets/external-secrets/0.10.4/charts/bitwarden-sdk-server/templates/NOTES.txt new file mode 100644 index 0000000000..46b671c6a3 --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/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/charts/external-secrets/external-secrets/0.10.4/charts/bitwarden-sdk-server/templates/_helpers.tpl b/charts/external-secrets/external-secrets/0.10.4/charts/bitwarden-sdk-server/templates/_helpers.tpl new file mode 100644 index 0000000000..a5e0da3cca --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/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/charts/external-secrets/external-secrets/0.10.4/charts/bitwarden-sdk-server/templates/deployment.yaml b/charts/external-secrets/external-secrets/0.10.4/charts/bitwarden-sdk-server/templates/deployment.yaml new file mode 100644 index 0000000000..06e28820a9 --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/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/charts/external-secrets/external-secrets/0.10.4/charts/bitwarden-sdk-server/templates/service.yaml b/charts/external-secrets/external-secrets/0.10.4/charts/bitwarden-sdk-server/templates/service.yaml new file mode 100644 index 0000000000..88e2d668b5 --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/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/charts/external-secrets/external-secrets/0.10.4/charts/bitwarden-sdk-server/templates/serviceaccount.yaml b/charts/external-secrets/external-secrets/0.10.4/charts/bitwarden-sdk-server/templates/serviceaccount.yaml new file mode 100644 index 0000000000..fef7bad653 --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/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/charts/external-secrets/external-secrets/0.10.4/charts/bitwarden-sdk-server/tests/__snapshot__/deployment_test.yaml.snap b/charts/external-secrets/external-secrets/0.10.4/charts/bitwarden-sdk-server/tests/__snapshot__/deployment_test.yaml.snap new file mode 100644 index 0000000000..2fbcdb118c --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/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/charts/external-secrets/external-secrets/0.10.4/charts/bitwarden-sdk-server/tests/deployment_test.yaml b/charts/external-secrets/external-secrets/0.10.4/charts/bitwarden-sdk-server/tests/deployment_test.yaml new file mode 100644 index 0000000000..bb4e2f4f50 --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/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/charts/external-secrets/external-secrets/0.10.4/charts/bitwarden-sdk-server/values.yaml b/charts/external-secrets/external-secrets/0.10.4/charts/bitwarden-sdk-server/values.yaml new file mode 100644 index 0000000000..f0424afbad --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/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/charts/external-secrets/external-secrets/0.10.4/questions.yaml b/charts/external-secrets/external-secrets/0.10.4/questions.yaml new file mode 100644 index 0000000000..31008999d3 --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/questions.yaml @@ -0,0 +1,8 @@ +questions: +- variable: installCRDs + default: false + required: true + description: "If true, Install and upgrade CRDs through helm chart" + type: boolean + label: Install CRDs + diff --git a/charts/external-secrets/external-secrets/0.10.4/templates/NOTES.txt b/charts/external-secrets/external-secrets/0.10.4/templates/NOTES.txt new file mode 100644 index 0000000000..ffa0fc7e18 --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/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/charts/external-secrets/external-secrets/0.10.4/templates/_helpers.tpl b/charts/external-secrets/external-secrets/0.10.4/templates/_helpers.tpl new file mode 100644 index 0000000000..d5eea07593 --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/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/charts/external-secrets/external-secrets/0.10.4/templates/cert-controller-deployment.yaml b/charts/external-secrets/external-secrets/0.10.4/templates/cert-controller-deployment.yaml new file mode 100644 index 0000000000..a843f045a0 --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/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/charts/external-secrets/external-secrets/0.10.4/templates/cert-controller-poddisruptionbudget.yaml b/charts/external-secrets/external-secrets/0.10.4/templates/cert-controller-poddisruptionbudget.yaml new file mode 100644 index 0000000000..e61cb8ebcf --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/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/charts/external-secrets/external-secrets/0.10.4/templates/cert-controller-rbac.yaml b/charts/external-secrets/external-secrets/0.10.4/templates/cert-controller-rbac.yaml new file mode 100644 index 0000000000..84a0c110bd --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/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/charts/external-secrets/external-secrets/0.10.4/templates/cert-controller-service.yaml b/charts/external-secrets/external-secrets/0.10.4/templates/cert-controller-service.yaml new file mode 100644 index 0000000000..12cb4f4dae --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/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/charts/external-secrets/external-secrets/0.10.4/templates/cert-controller-serviceaccount.yaml b/charts/external-secrets/external-secrets/0.10.4/templates/cert-controller-serviceaccount.yaml new file mode 100644 index 0000000000..6a36f9d713 --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/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/charts/external-secrets/external-secrets/0.10.4/templates/crds/acraccesstoken.yaml b/charts/external-secrets/external-secrets/0.10.4/templates/crds/acraccesstoken.yaml new file mode 100644 index 0000000000..3ad09232dd --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/templates/crds/acraccesstoken.yaml @@ -0,0 +1,204 @@ +{{- 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.3 + labels: + external-secrets.io/component: controller + name: acraccesstokens.generators.external-secrets.io +spec: + group: generators.external-secrets.io + names: + categories: + - external-secrets + - external-secrets-generators + 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/charts/external-secrets/external-secrets/0.10.4/templates/crds/clusterexternalsecret.yaml b/charts/external-secrets/external-secrets/0.10.4/templates/crds/clusterexternalsecret.yaml new file mode 100644 index 0000000000..c0be1fe031 --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/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.3 + labels: + external-secrets.io/component: controller + name: clusterexternalsecrets.external-secrets.io +spec: + group: external-secrets.io + names: + categories: + - external-secrets + 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/charts/external-secrets/external-secrets/0.10.4/templates/crds/clustersecretstore.yaml b/charts/external-secrets/external-secrets/0.10.4/templates/crds/clustersecretstore.yaml new file mode 100644 index 0000000000..22c8009a60 --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/templates/crds/clustersecretstore.yaml @@ -0,0 +1,4640 @@ +{{- 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.3 + labels: + external-secrets.io/component: controller + name: clustersecretstores.external-secrets.io +spec: + group: external-secrets.io + names: + categories: + - external-secrets + 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 + previder: + description: Previder configures this store to sync secrets using the Previder provider + properties: + auth: + description: PreviderAuth contains a secretRef for credentials. + properties: + secretRef: + description: PreviderAuthSecretRef holds secret references for Previder Vault credentials. + properties: + accessToken: + description: The 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 + required: + - accessToken + type: object + type: object + baseUri: + type: string + required: + - auth + 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/esc + 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 + project: + description: Project is the name of the Pulumi ESC project the environment belongs to. + type: string + required: + - accessToken + - environment + - organization + - project + 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/charts/external-secrets/external-secrets/0.10.4/templates/crds/ecrauthorizationtoken.yaml b/charts/external-secrets/external-secrets/0.10.4/templates/crds/ecrauthorizationtoken.yaml new file mode 100644 index 0000000000..f018059228 --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/templates/crds/ecrauthorizationtoken.yaml @@ -0,0 +1,178 @@ +{{- 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.3 + labels: + external-secrets.io/component: controller + name: ecrauthorizationtokens.generators.external-secrets.io +spec: + group: generators.external-secrets.io + names: + categories: + - external-secrets + - external-secrets-generators + 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/charts/external-secrets/external-secrets/0.10.4/templates/crds/externalsecret.yaml b/charts/external-secrets/external-secrets/0.10.4/templates/crds/externalsecret.yaml new file mode 100644 index 0000000000..c2dabe680a --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/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.3 + labels: + external-secrets.io/component: controller + name: externalsecrets.external-secrets.io +spec: + group: external-secrets.io + names: + categories: + - external-secrets + 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/charts/external-secrets/external-secrets/0.10.4/templates/crds/fake.yaml b/charts/external-secrets/external-secrets/0.10.4/templates/crds/fake.yaml new file mode 100644 index 0000000000..6aa0317634 --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/templates/crds/fake.yaml @@ -0,0 +1,87 @@ +{{- 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.3 + labels: + external-secrets.io/component: controller + name: fakes.generators.external-secrets.io +spec: + group: generators.external-secrets.io + names: + categories: + - external-secrets + - external-secrets-generators + 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/charts/external-secrets/external-secrets/0.10.4/templates/crds/gcraccesstoken.yaml b/charts/external-secrets/external-secrets/0.10.4/templates/crds/gcraccesstoken.yaml new file mode 100644 index 0000000000..2da8a843f7 --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/templates/crds/gcraccesstoken.yaml @@ -0,0 +1,139 @@ +{{- 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.3 + labels: + external-secrets.io/component: controller + name: gcraccesstokens.generators.external-secrets.io +spec: + group: generators.external-secrets.io + names: + categories: + - external-secrets + - external-secrets-generators + 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/charts/external-secrets/external-secrets/0.10.4/templates/crds/githubaccesstoken.yaml b/charts/external-secrets/external-secrets/0.10.4/templates/crds/githubaccesstoken.yaml new file mode 100644 index 0000000000..a94a89f417 --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/templates/crds/githubaccesstoken.yaml @@ -0,0 +1,113 @@ +{{- 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.3 + labels: + external-secrets.io/component: controller + name: githubaccesstokens.generators.external-secrets.io +spec: + group: generators.external-secrets.io + names: + categories: + - external-secrets + - external-secrets-generators + 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/charts/external-secrets/external-secrets/0.10.4/templates/crds/password.yaml b/charts/external-secrets/external-secrets/0.10.4/templates/crds/password.yaml new file mode 100644 index 0000000000..ce250e8c55 --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/templates/crds/password.yaml @@ -0,0 +1,109 @@ +{{- 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.3 + labels: + external-secrets.io/component: controller + name: passwords.generators.external-secrets.io +spec: + group: generators.external-secrets.io + names: + categories: + - external-secrets + - external-secrets-generators + 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/charts/external-secrets/external-secrets/0.10.4/templates/crds/pushsecret.yaml b/charts/external-secrets/external-secrets/0.10.4/templates/crds/pushsecret.yaml new file mode 100644 index 0000000000..596b565ebe --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/templates/crds/pushsecret.yaml @@ -0,0 +1,388 @@ +{{- 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.3 + labels: + external-secrets.io/component: controller + name: pushsecrets.external-secrets.io +spec: + group: external-secrets.io + names: + categories: + - external-secrets + 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/charts/external-secrets/external-secrets/0.10.4/templates/crds/secretstore.yaml b/charts/external-secrets/external-secrets/0.10.4/templates/crds/secretstore.yaml new file mode 100644 index 0000000000..b5cfb3b09f --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/templates/crds/secretstore.yaml @@ -0,0 +1,4640 @@ +{{- 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.3 + labels: + external-secrets.io/component: controller + name: secretstores.external-secrets.io +spec: + group: external-secrets.io + names: + categories: + - external-secrets + 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 + previder: + description: Previder configures this store to sync secrets using the Previder provider + properties: + auth: + description: PreviderAuth contains a secretRef for credentials. + properties: + secretRef: + description: PreviderAuthSecretRef holds secret references for Previder Vault credentials. + properties: + accessToken: + description: The 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 + required: + - accessToken + type: object + type: object + baseUri: + type: string + required: + - auth + 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/esc + 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 + project: + description: Project is the name of the Pulumi ESC project the environment belongs to. + type: string + required: + - accessToken + - environment + - organization + - project + 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/charts/external-secrets/external-secrets/0.10.4/templates/crds/uuid.yaml b/charts/external-secrets/external-secrets/0.10.4/templates/crds/uuid.yaml new file mode 100644 index 0000000000..d12aaf2f7e --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/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.3 + labels: + external-secrets.io/component: controller + name: uuids.generators.external-secrets.io +spec: + group: generators.external-secrets.io + names: + categories: + - external-secrets + - external-secrets-generators + kind: UUID + listKind: UUIDList + plural: uuids + shortNames: + - uuids + singular: uuid + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: UUID generates a version 1 UUID (e56657e3-764f-11ef-a397-65231a88c216). + 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/charts/external-secrets/external-secrets/0.10.4/templates/crds/vaultdynamicsecret.yaml b/charts/external-secrets/external-secrets/0.10.4/templates/crds/vaultdynamicsecret.yaml new file mode 100644 index 0000000000..8459dbbac3 --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/templates/crds/vaultdynamicsecret.yaml @@ -0,0 +1,708 @@ +{{- 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.3 + labels: + external-secrets.io/component: controller + name: vaultdynamicsecrets.generators.external-secrets.io +spec: + group: generators.external-secrets.io + names: + categories: + - external-secrets + - external-secrets-generators + 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/charts/external-secrets/external-secrets/0.10.4/templates/crds/webhook.yaml b/charts/external-secrets/external-secrets/0.10.4/templates/crds/webhook.yaml new file mode 100644 index 0000000000..9e0c42cc1f --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/templates/crds/webhook.yaml @@ -0,0 +1,158 @@ +{{- 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.3 + labels: + external-secrets.io/component: controller + name: webhooks.generators.external-secrets.io +spec: + group: generators.external-secrets.io + names: + categories: + - external-secrets + - external-secrets-generators + 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/charts/external-secrets/external-secrets/0.10.4/templates/deployment.yaml b/charts/external-secrets/external-secrets/0.10.4/templates/deployment.yaml new file mode 100644 index 0000000000..75a908e635 --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/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/charts/external-secrets/external-secrets/0.10.4/templates/extra-manifests.yaml b/charts/external-secrets/external-secrets/0.10.4/templates/extra-manifests.yaml new file mode 100644 index 0000000000..1dfe8f48fe --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/templates/extra-manifests.yaml @@ -0,0 +1,4 @@ +{{- range .Values.extraObjects }} +--- +{{ include "external-secrets.render" (dict "value" . "context" $) }} +{{- end }} diff --git a/charts/external-secrets/external-secrets/0.10.4/templates/poddisruptionbudget.yaml b/charts/external-secrets/external-secrets/0.10.4/templates/poddisruptionbudget.yaml new file mode 100644 index 0000000000..7b75ca3f4e --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/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/charts/external-secrets/external-secrets/0.10.4/templates/rbac.yaml b/charts/external-secrets/external-secrets/0.10.4/templates/rbac.yaml new file mode 100644 index 0000000000..4f4ab48fe8 --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/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/charts/external-secrets/external-secrets/0.10.4/templates/service.yaml b/charts/external-secrets/external-secrets/0.10.4/templates/service.yaml new file mode 100644 index 0000000000..94859a34ec --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/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/charts/external-secrets/external-secrets/0.10.4/templates/serviceaccount.yaml b/charts/external-secrets/external-secrets/0.10.4/templates/serviceaccount.yaml new file mode 100644 index 0000000000..ceaa98e1c5 --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/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/charts/external-secrets/external-secrets/0.10.4/templates/servicemonitor.yaml b/charts/external-secrets/external-secrets/0.10.4/templates/servicemonitor.yaml new file mode 100644 index 0000000000..31451791ae --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/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/charts/external-secrets/external-secrets/0.10.4/templates/validatingwebhook.yaml b/charts/external-secrets/external-secrets/0.10.4/templates/validatingwebhook.yaml new file mode 100644 index 0000000000..63b39763f9 --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/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/charts/external-secrets/external-secrets/0.10.4/templates/webhook-certificate.yaml b/charts/external-secrets/external-secrets/0.10.4/templates/webhook-certificate.yaml new file mode 100644 index 0000000000..adb19fd95d --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/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/charts/external-secrets/external-secrets/0.10.4/templates/webhook-deployment.yaml b/charts/external-secrets/external-secrets/0.10.4/templates/webhook-deployment.yaml new file mode 100644 index 0000000000..7419a426b2 --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/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/charts/external-secrets/external-secrets/0.10.4/templates/webhook-poddisruptionbudget.yaml b/charts/external-secrets/external-secrets/0.10.4/templates/webhook-poddisruptionbudget.yaml new file mode 100644 index 0000000000..58345ba689 --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/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/charts/external-secrets/external-secrets/0.10.4/templates/webhook-secret.yaml b/charts/external-secrets/external-secrets/0.10.4/templates/webhook-secret.yaml new file mode 100644 index 0000000000..fa7760ed64 --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/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/charts/external-secrets/external-secrets/0.10.4/templates/webhook-service.yaml b/charts/external-secrets/external-secrets/0.10.4/templates/webhook-service.yaml new file mode 100644 index 0000000000..59dbddc953 --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/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/charts/external-secrets/external-secrets/0.10.4/templates/webhook-serviceaccount.yaml b/charts/external-secrets/external-secrets/0.10.4/templates/webhook-serviceaccount.yaml new file mode 100644 index 0000000000..1936218425 --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/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/charts/external-secrets/external-secrets/0.10.4/values.schema.json b/charts/external-secrets/external-secrets/0.10.4/values.schema.json new file mode 100644 index 0000000000..08cef96a31 --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/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/charts/external-secrets/external-secrets/0.10.4/values.yaml b/charts/external-secrets/external-secrets/0.10.4/values.yaml new file mode 100644 index 0000000000..21f4a94c39 --- /dev/null +++ b/charts/external-secrets/external-secrets/0.10.4/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: oci.external-secrets.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: oci.external-secrets.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: oci.external-secrets.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/charts/speedscale/speedscale-operator/2.2.467/.helmignore b/charts/speedscale/speedscale-operator/2.2.467/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/charts/speedscale/speedscale-operator/2.2.467/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/charts/speedscale/speedscale-operator/2.2.467/Chart.yaml b/charts/speedscale/speedscale-operator/2.2.467/Chart.yaml new file mode 100644 index 0000000000..00091fcdfe --- /dev/null +++ b/charts/speedscale/speedscale-operator/2.2.467/Chart.yaml @@ -0,0 +1,27 @@ +annotations: + catalog.cattle.io/certified: partner + catalog.cattle.io/display-name: Speedscale Operator + catalog.cattle.io/kube-version: '>= 1.17.0-0' + catalog.cattle.io/release-name: speedscale-operator +apiVersion: v1 +appVersion: 2.2.467 +description: Stress test your APIs with real world scenarios. Collect and replay + traffic without scripting. +home: https://speedscale.com +icon: file://assets/icons/speedscale-operator.png +keywords: +- speedscale +- test +- testing +- regression +- reliability +- load +- replay +- network +- traffic +kubeVersion: '>= 1.17.0-0' +maintainers: +- email: support@speedscale.com + name: Speedscale Support +name: speedscale-operator +version: 2.2.467 diff --git a/charts/speedscale/speedscale-operator/2.2.467/LICENSE b/charts/speedscale/speedscale-operator/2.2.467/LICENSE new file mode 100644 index 0000000000..b78723d62f --- /dev/null +++ b/charts/speedscale/speedscale-operator/2.2.467/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2021 Speedscale + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/charts/speedscale/speedscale-operator/2.2.467/README.md b/charts/speedscale/speedscale-operator/2.2.467/README.md new file mode 100644 index 0000000000..6ca25eed9d --- /dev/null +++ b/charts/speedscale/speedscale-operator/2.2.467/README.md @@ -0,0 +1,111 @@ +![GitHub Tag](https://img.shields.io/github/v/tag/speedscale/operator-helm) + + +# Speedscale Operator + +The [Speedscale](https://www.speedscale.com) Operator is a [Kubernetes operator](https://kubernetes.io/docs/concepts/extend-kubernetes/operator/) +that watches for deployments to be applied to the cluster and takes action based on annotations. The operator +can inject a proxy to capture traffic into or out of applications, or setup an isolation test environment around +a deployment for testing. The operator itself is a deployment that will be always present on the cluster once +the helm chart is installed. + +## Prerequisites + +- Kubernetes 1.20+ +- Helm 3+ +- Appropriate [network and firewall configuration](https://docs.speedscale.com/reference/networking) for Speedscale cloud and webhook traffic + +## Get Repo Info + +```bash +helm repo add speedscale https://speedscale.github.io/operator-helm/ +helm repo update +``` + +_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + +## Install Chart + +An API key is required. Sign up for a [free Speedscale trial](https://speedscale.com/free-trial/) if you do not have one. + +```bash +helm install speedscale-operator speedscale/speedscale-operator \ + -n speedscale \ + --create-namespace \ + --set apiKey= \ + --set clusterName= +``` + +_See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._ + +### Pre-install job failure + +We use pre-install job to check provided API key and provision some of the required resources. + +If the job failed during the installation, you'll see the following error during install: + +``` +Error: INSTALLATION FAILED: failed pre-install: job failed: BackoffLimitExceeded +``` + +You can inspect the logs using this command: + +```bash +kubectl -n speedscale logs job/speedscale-operator-pre-install +``` + +After fixing the error, uninstall the helm release, delete the failed job +and try installing again: + +```bash +helm -n speedscale uninstall speedscale-operator +kubectl -n speedscale delete job speedscale-operator-pre-install +``` + +## Uninstall Chart + +```bash +helm -n speedscale uninstall speedscale-operator +``` + +This removes all the Kubernetes components associated with the chart and deletes the release. + +_See [helm uninstall](https://helm.sh/docs/helm/helm_uninstall/) for command documentation._ + +CRDs created by this chart are not removed by default and should be manually cleaned up: + +```bash +kubectl delete crd trafficreplays.speedscale.com +``` + +## Upgrading Chart + +```bash +helm repo update +helm -n speedscale upgrade speedscale-operator speedscale/speedscale-operator +``` + +Resources capturing traffic will need to be rolled to pick up the latest +Speedscale sidecar. Use the rollout restart command for each namespace and +resource type: + +```bash +kubectl -n rollout restart deployment +``` + +With Helm v3, CRDs created by this chart are not updated by default +and should be manually updated. +Consult also the [Helm Documentation on CRDs](https://helm.sh/docs/chart_best_practices/custom_resource_definitions). + +_See [helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) for command documentation._ + +### Upgrading an existing Release to a new version + +A major chart version change (like v1.2.3 -> v2.0.0) indicates that there is an +incompatible breaking change needing manual actions. + + +## Help + +Speedscale docs information available at [docs.speedscale.com](https://docs.speedscale.com) or join us +on the [Speedscale community Slack](https://join.slack.com/t/speedscalecommunity/shared_invite/zt-x5rcrzn4-XHG1QqcHNXIM~4yozRrz8A)! diff --git a/charts/speedscale/speedscale-operator/2.2.467/app-readme.md b/charts/speedscale/speedscale-operator/2.2.467/app-readme.md new file mode 100644 index 0000000000..6ca25eed9d --- /dev/null +++ b/charts/speedscale/speedscale-operator/2.2.467/app-readme.md @@ -0,0 +1,111 @@ +![GitHub Tag](https://img.shields.io/github/v/tag/speedscale/operator-helm) + + +# Speedscale Operator + +The [Speedscale](https://www.speedscale.com) Operator is a [Kubernetes operator](https://kubernetes.io/docs/concepts/extend-kubernetes/operator/) +that watches for deployments to be applied to the cluster and takes action based on annotations. The operator +can inject a proxy to capture traffic into or out of applications, or setup an isolation test environment around +a deployment for testing. The operator itself is a deployment that will be always present on the cluster once +the helm chart is installed. + +## Prerequisites + +- Kubernetes 1.20+ +- Helm 3+ +- Appropriate [network and firewall configuration](https://docs.speedscale.com/reference/networking) for Speedscale cloud and webhook traffic + +## Get Repo Info + +```bash +helm repo add speedscale https://speedscale.github.io/operator-helm/ +helm repo update +``` + +_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + +## Install Chart + +An API key is required. Sign up for a [free Speedscale trial](https://speedscale.com/free-trial/) if you do not have one. + +```bash +helm install speedscale-operator speedscale/speedscale-operator \ + -n speedscale \ + --create-namespace \ + --set apiKey= \ + --set clusterName= +``` + +_See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._ + +### Pre-install job failure + +We use pre-install job to check provided API key and provision some of the required resources. + +If the job failed during the installation, you'll see the following error during install: + +``` +Error: INSTALLATION FAILED: failed pre-install: job failed: BackoffLimitExceeded +``` + +You can inspect the logs using this command: + +```bash +kubectl -n speedscale logs job/speedscale-operator-pre-install +``` + +After fixing the error, uninstall the helm release, delete the failed job +and try installing again: + +```bash +helm -n speedscale uninstall speedscale-operator +kubectl -n speedscale delete job speedscale-operator-pre-install +``` + +## Uninstall Chart + +```bash +helm -n speedscale uninstall speedscale-operator +``` + +This removes all the Kubernetes components associated with the chart and deletes the release. + +_See [helm uninstall](https://helm.sh/docs/helm/helm_uninstall/) for command documentation._ + +CRDs created by this chart are not removed by default and should be manually cleaned up: + +```bash +kubectl delete crd trafficreplays.speedscale.com +``` + +## Upgrading Chart + +```bash +helm repo update +helm -n speedscale upgrade speedscale-operator speedscale/speedscale-operator +``` + +Resources capturing traffic will need to be rolled to pick up the latest +Speedscale sidecar. Use the rollout restart command for each namespace and +resource type: + +```bash +kubectl -n rollout restart deployment +``` + +With Helm v3, CRDs created by this chart are not updated by default +and should be manually updated. +Consult also the [Helm Documentation on CRDs](https://helm.sh/docs/chart_best_practices/custom_resource_definitions). + +_See [helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) for command documentation._ + +### Upgrading an existing Release to a new version + +A major chart version change (like v1.2.3 -> v2.0.0) indicates that there is an +incompatible breaking change needing manual actions. + + +## Help + +Speedscale docs information available at [docs.speedscale.com](https://docs.speedscale.com) or join us +on the [Speedscale community Slack](https://join.slack.com/t/speedscalecommunity/shared_invite/zt-x5rcrzn4-XHG1QqcHNXIM~4yozRrz8A)! diff --git a/charts/speedscale/speedscale-operator/2.2.467/questions.yaml b/charts/speedscale/speedscale-operator/2.2.467/questions.yaml new file mode 100644 index 0000000000..29aee38958 --- /dev/null +++ b/charts/speedscale/speedscale-operator/2.2.467/questions.yaml @@ -0,0 +1,9 @@ +questions: +- variable: apiKey + default: "fffffffffffffffffffffffffffffffffffffffffffff" + description: "An API key is required to connect to the Speedscale cloud." + required: true + type: string + label: API Key + group: Authentication + diff --git a/charts/speedscale/speedscale-operator/2.2.467/templates/NOTES.txt b/charts/speedscale/speedscale-operator/2.2.467/templates/NOTES.txt new file mode 100644 index 0000000000..cabb59b175 --- /dev/null +++ b/charts/speedscale/speedscale-operator/2.2.467/templates/NOTES.txt @@ -0,0 +1,12 @@ +Thank you for installing the Speedscale Operator! + +Next you'll need to add the Speedscale Proxy Sidecar to your deployments. +See https://docs.speedscale.com/setup/sidecar/install/ + +If upgrading use the rollout restart command for each namespace and resource +type to ensure Speedscale sidecars are updated: + + kubectl -n rollout restart deployment + +Once your deployment is running the sidecar your service will show up on +https://app.speedscale.com/. diff --git a/charts/speedscale/speedscale-operator/2.2.467/templates/admission.yaml b/charts/speedscale/speedscale-operator/2.2.467/templates/admission.yaml new file mode 100644 index 0000000000..301748a61d --- /dev/null +++ b/charts/speedscale/speedscale-operator/2.2.467/templates/admission.yaml @@ -0,0 +1,209 @@ +{{- $cacrt := "" -}} +{{- $crt := "" -}} +{{- $key := "" -}} +{{- $s := (lookup "v1" "Secret" .Release.Namespace "speedscale-webhook-certs") -}} +{{- if $s -}} +{{- $cacrt = index $s.data "ca.crt" | default (index $s.data "tls.crt") | b64dec -}} +{{- $crt = index $s.data "tls.crt" | b64dec -}} +{{- $key = index $s.data "tls.key" | b64dec -}} +{{ else }} +{{- $altNames := list ( printf "speedscale-operator.%s" .Release.Namespace ) ( printf "speedscale-operator.%s.svc" .Release.Namespace ) -}} +{{- $ca := genCA "speedscale-operator" 3650 -}} +{{- $cert := genSignedCert "speedscale-operator" nil $altNames 3650 $ca -}} +{{- $cacrt = $ca.Cert -}} +{{- $crt = $cert.Cert -}} +{{- $key = $cert.Key -}} +{{- end -}} +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + creationTimestamp: null + name: speedscale-operator + annotations: + argocd.argoproj.io/hook: PreSync + {{- if .Values.globalAnnotations }} +{{ toYaml .Values.globalAnnotations | indent 4}} + {{- end }} +webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + caBundle: {{ $cacrt | b64enc }} + service: + name: speedscale-operator + namespace: {{ .Release.Namespace }} + path: /mutate + failurePolicy: Ignore + name: sidecar.speedscale.com + namespaceSelector: + matchExpressions: + - key: kubernetes.io/metadata.name + operator: "NotIn" + values: + - kube-system + - kube-node-lease + {{- if .Values.namespaceSelector }} + - key: kubernetes.io/metadata.name + operator: "In" + values: + {{- range .Values.namespaceSelector }} + - {{ . | quote }} + {{- end }} + {{- end }} + reinvocationPolicy: IfNeeded + rules: + - apiGroups: + - apps + - batch + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + - DELETE + resources: + - deployments + - statefulsets + - daemonsets + - jobs + - replicasets + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + - DELETE + resources: + - pods + - apiGroups: + - argoproj.io + apiVersions: + - "*" + operations: + - CREATE + - UPDATE + - DELETE + resources: + - rollouts + sideEffects: None + timeoutSeconds: 10 +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + creationTimestamp: null + name: speedscale-operator-replay + annotations: + argocd.argoproj.io/hook: PreSync + {{- if .Values.globalAnnotations }} +{{ toYaml .Values.globalAnnotations | indent 4}} + {{- end }} +webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + caBundle: {{ $cacrt | b64enc }} + service: + name: speedscale-operator + namespace: {{ .Release.Namespace }} + path: /mutate-speedscale-com-v1-trafficreplay + failurePolicy: Fail + name: replay.speedscale.com + namespaceSelector: + matchExpressions: + - key: kubernetes.io/metadata.name + operator: "NotIn" + values: + - kube-system + - kube-node-lease + {{- if .Values.namespaceSelector }} + - key: kubernetes.io/metadata.name + operator: "In" + values: + {{- range .Values.namespaceSelector }} + - {{ . | quote }} + {{- end }} + {{- end }} + rules: + - apiGroups: + - speedscale.com + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - trafficreplays + sideEffects: None + timeoutSeconds: 10 +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + creationTimestamp: null + name: speedscale-operator-replay + annotations: + argocd.argoproj.io/hook: PreSync + {{- if .Values.globalAnnotations }} +{{ toYaml .Values.globalAnnotations | indent 4}} + {{- end }} +webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + caBundle: {{ $cacrt | b64enc }} + service: + name: speedscale-operator + namespace: {{ .Release.Namespace }} + path: /validate-speedscale-com-v1-trafficreplay + failurePolicy: Fail + name: replay.speedscale.com + namespaceSelector: + matchExpressions: + - key: kubernetes.io/metadata.name + operator: "NotIn" + values: + - kube-system + - kube-node-lease + {{- if .Values.namespaceSelector }} + - key: kubernetes.io/metadata.name + operator: "In" + values: + {{- range .Values.namespaceSelector }} + - {{ . | quote }} + {{- end }} + {{- end }} + rules: + - apiGroups: + - speedscale.com + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + - DELETE + resources: + - trafficreplays + sideEffects: None + timeoutSeconds: 10 +--- +apiVersion: v1 +kind: Secret +metadata: + annotations: + helm.sh/hook: pre-install + helm.sh/hook-delete-policy: before-hook-creation + {{- if .Values.globalAnnotations }} +{{ toYaml .Values.globalAnnotations | indent 4}} + {{- end }} + creationTimestamp: null + name: speedscale-webhook-certs + namespace: {{ .Release.Namespace }} +type: kubernetes.io/tls +data: + ca.crt: {{ $cacrt | b64enc }} + tls.crt: {{ $crt | b64enc }} + tls.key: {{ $key | b64enc }} diff --git a/charts/speedscale/speedscale-operator/2.2.467/templates/configmap.yaml b/charts/speedscale/speedscale-operator/2.2.467/templates/configmap.yaml new file mode 100644 index 0000000000..04dfda91aa --- /dev/null +++ b/charts/speedscale/speedscale-operator/2.2.467/templates/configmap.yaml @@ -0,0 +1,43 @@ +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: speedscale-operator + namespace: {{ .Release.Namespace }} + annotations: + argocd.argoproj.io/hook: PreSync + {{- if .Values.globalAnnotations }} +{{ toYaml .Values.globalAnnotations | indent 4}} + {{- end }} +data: + CLUSTER_NAME: {{ .Values.clusterName }} + IMAGE_PULL_POLICY: {{ .Values.image.pullPolicy }} + IMAGE_PULL_SECRETS: "" + IMAGE_REGISTRY: {{ .Values.image.registry }} + IMAGE_TAG: {{ .Values.image.tag }} + INSTANCE_ID: '{{- $cm := (lookup "v1" "ConfigMap" .Release.Namespace "speedscale-operator") -}}{{ if $cm }}{{ $cm.data.INSTANCE_ID }}{{ else }}{{ ( printf "%s-%s" .Values.clusterName uuidv4 ) }}{{ end }}' + LOG_LEVEL: {{ .Values.logLevel }} + SPEEDSCALE_DLP_CONFIG: {{ .Values.dlp.config }} + SPEEDSCALE_FILTER_RULE: {{ .Values.filterRule }} + TELEMETRY_INTERVAL: 1s + WITH_DLP: {{ .Values.dlp.enabled | quote }} + WITH_INSPECTOR: {{ .Values.dashboardAccess | quote }} + API_KEY_SECRET_NAME: {{ .Values.apiKeySecret | quote }} + DEPLOY_DEMO: {{ .Values.deployDemo | quote }} + GLOBAL_ANNOTATIONS: {{ .Values.globalAnnotations | toJson | quote }} + GLOBAL_LABELS: {{ .Values.globalLabels | toJson | quote }} + {{- if .Values.http_proxy }} + HTTP_PROXY: {{ .Values.http_proxy }} + {{- end }} + {{- if .Values.https_proxy }} + HTTPS_PROXY: {{ .Values.https_proxy }} + {{- end }} + {{- if .Values.no_proxy }} + NO_PROXY: {{ .Values.no_proxy }} + {{- end }} + PRIVILEGED_SIDECARS: {{ .Values.privilegedSidecars | quote }} + DISABLE_SMARTDNS: {{ .Values.disableSidecarSmartReverseDNS | quote }} + SIDECAR_CONFIG: {{ .Values.sidecar | toJson | quote }} + FORWARDER_CONFIG: {{ .Values.forwarder | toJson | quote }} + TEST_PREP_TIMEOUT: {{ .Values.operator.test_prep_timeout }} + CONTROL_PLANE_TIMEOUT: {{ .Values.operator.control_plane_timeout }} diff --git a/charts/speedscale/speedscale-operator/2.2.467/templates/crds/trafficreplays.yaml b/charts/speedscale/speedscale-operator/2.2.467/templates/crds/trafficreplays.yaml new file mode 100644 index 0000000000..aea3315479 --- /dev/null +++ b/charts/speedscale/speedscale-operator/2.2.467/templates/crds/trafficreplays.yaml @@ -0,0 +1,525 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + creationTimestamp: null + name: trafficreplays.speedscale.com +spec: + group: speedscale.com + names: + kind: TrafficReplay + listKind: TrafficReplayList + plural: trafficreplays + shortNames: + - replay + singular: trafficreplay + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.active + name: Active + type: boolean + - jsonPath: .spec.mode + name: Mode + type: string + - jsonPath: .status.conditions[-1:].message + name: Status + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: TrafficReplay is the Schema for the trafficreplays API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: TrafficReplaySpec defines the desired state of TrafficReplay + properties: + buildTag: + description: |- + BuildTag links a unique tag, build hash, etc. to the generated + traffic replay report. That way you can connect the report results to the + version of the code that was tested. + type: string + cleanup: + description: |- + Cleanup is the name of cleanup mode used for this TrafficReplay. Set to + "none" to leave resources in the state they were during the replay. The + default mode "inventory" will revert the environment to the state it was + before the replay. + enum: + - inventory + - all + - none + type: string + collectLogs: + description: |- + CollectLogs enables or disables log collection from target + workload. Defaults to true. + DEPRECATED: use TestReport.ActualConfig.Cluster.CollectLogs + type: boolean + configChecksum: + description: |- + ConfigChecksum, managed my the operator, is the SHA1 checksum of the + configuration. + type: string + customURL: + description: |- + CustomURL specifies a custom URL to send *ALL* traffic to. Use + Workload.CustomURI to send traffic to a specific URL for only that + workload. + type: string + generatorLowData: + description: |- + GeneratorLowData forces the generator into a high + efficiency/low data output mode. This is ideal for high volume + performance tests. Defaults to false. + DEPRECATED + type: boolean + mode: + description: Mode is the name of replay mode used for this TrafficReplay. + enum: + - full-replay + - responder-only + - generator-only + type: string + needsReport: + description: Indicates whether a responder-only replay needs a report. + type: boolean + proxyMode: + description: |- + ProxyMode defines proxy operational mode used with injected sidecar. + DEPRECATED + type: string + responderLowData: + description: |- + ResponderLowData forces the responder into a high + efficiency/low data output mode. This is ideal for high volume + performance tests. Defaults to false. + DEPRECATED + type: boolean + secretRefs: + description: |- + SecretRefs hold the references to the secrets which contain + various secrets like (e.g. short-lived JWTs to be used by the generator + for authorization with HTTP calls). + items: + description: |- + LocalObjectReference contains enough information to locate the referenced + Kubernetes resource object. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + type: array + sidecar: + description: |- + Sidecar defines sidecar specific configuration. + DEPRECATED: use Workloads + properties: + inject: + description: 'DEPRECATED: do not use' + type: boolean + patch: + description: Patch is .yaml file patch for the Workload + format: byte + type: string + tls: + properties: + in: + description: In provides configuration for sidecar inbound + TLS. + properties: + private: + description: Private is the filename of the TLS inbound + private key. + type: string + public: + description: Public is the filename of the TLS inbound + public key. + type: string + secret: + description: Secret is a secret with the TLS keys to use + for inbound traffic. + type: string + type: object + mutual: + description: Mutual provides configuration for sidecar mutual + TLS. + properties: + private: + description: Private is the filename of the mutual TLS + private key. + type: string + public: + description: Public is the filename of the mutual TLS + public key. + type: string + secret: + description: Secret is a secret with the mutual TLS keys. + type: string + type: object + out: + description: |- + Out enables or disables TLS out on the + sidecar during replay. + type: boolean + type: object + type: object + snapshotID: + description: |- + SnapshotID is the id of the traffic snapshot for this + TrafficReplay. + type: string + testConfigID: + description: |- + TestConfigID is the id of the replay configuration to be used + by the generator and responder for the TrafficReplay. + type: string + timeout: + description: |- + Timeout is the time to wait for replay test to finish. Defaults + to value of the `TIMEOUT` setting of the operator. + type: string + ttlAfterReady: + description: |- + TTLAfterReady provides a TTL (time to live) mechanism to limit + the lifetime of TrafficReplay object that have finished the execution and + reached its final state (either complete or failed). + type: string + workloadRef: + description: |- + WorkloadRef is the reference to the target workload (SUT) for + TrafficReplay. The operations will be performed in the namespace of the + target object. + DEPRECATED: use Workloads + properties: + apiVersion: + description: API version of the referenced object. + type: string + kind: + description: Kind of the referenced object. Defaults to "Deployment". + type: string + name: + description: |- + Name of the referenced object. Required when defining for a test unless a + custom URI is provided. Always required when defining mocks. + type: string + namespace: + description: Namespace of the referenced object. Defaults to the + TrafficReplay namespace. + type: string + required: + - name + type: object + workloads: + description: |- + Workloads define target workloads (SUT) for a TrafficReplay. Many + workloads may be provided, or none. Workloads may be modified and + restarted during replay to configure communication with a responder. + items: + description: |- + Workload represents a Kubernetes workload to be targeted during replay and + associated settings. + properties: + customURI: + description: |- + CustomURI will be target of the traffic instead of directly targeting + workload. This is required if a Ref is not specified. + type: string + inTrafficKey: + description: 'DEPRECATED: use Tests' + type: string + inTrafficKeys: + description: 'DEPRECATED: use Tests' + items: + type: string + type: array + mocks: + description: |- + Mocks are strings used to identify slices of outbound snapshot traffic to + mock for this workload and maps directly to a snapshot's `OutTraffic` + field. Snapshot egress traffic can be split across multiple slices where + each slice contains part of the traffic. A workload may specify multiple + keys and multiple workloads may specify the same key. + + + Only the traffic slices defined here will be mocked. A workload with no + keys defined will not mock any traffic. Pass '*' to mock all traffic. + + + Mock strings may only match part of the snapshot's `OutTraffic` key if the + string matches exactly one key. For example, the test string + `foo.example.com` would match the `OutTraffic` key of + my-service:foo.example.com:8080, as long as no other keys would match + `foo.example.com`. Multiple mocks must be specified for multiple keys + unless using '*'. + items: + type: string + type: array + outTrafficKeys: + description: 'DEPRECATED: use Mocks' + items: + type: string + type: array + ref: + description: |- + Ref is a reference to a cluster workload, like a deployment or a + statefulset. This is required unless a CustomURI is specified. + properties: + apiVersion: + description: API version of the referenced object. + type: string + kind: + description: Kind of the referenced object. Defaults to + "Deployment". + type: string + name: + description: |- + Name of the referenced object. Required when defining for a test unless a + custom URI is provided. Always required when defining mocks. + type: string + namespace: + description: Namespace of the referenced object. Defaults + to the TrafficReplay namespace. + type: string + required: + - name + type: object + routing: + description: Routing configures how workloads route egress traffic + to responders + enum: + - hostalias + - nat + type: string + sidecar: + description: |- + TODO: this is not implemented, come back and replace deprecated Sidecar with workload specific settings + Sidecar defines sidecar specific configuration. + properties: + inject: + description: 'DEPRECATED: do not use' + type: boolean + patch: + description: Patch is .yaml file patch for the Workload + format: byte + type: string + tls: + properties: + in: + description: In provides configuration for sidecar inbound + TLS. + properties: + private: + description: Private is the filename of the TLS + inbound private key. + type: string + public: + description: Public is the filename of the TLS inbound + public key. + type: string + secret: + description: Secret is a secret with the TLS keys + to use for inbound traffic. + type: string + type: object + mutual: + description: Mutual provides configuration for sidecar + mutual TLS. + properties: + private: + description: Private is the filename of the mutual + TLS private key. + type: string + public: + description: Public is the filename of the mutual + TLS public key. + type: string + secret: + description: Secret is a secret with the mutual + TLS keys. + type: string + type: object + out: + description: |- + Out enables or disables TLS out on the + sidecar during replay. + type: boolean + type: object + type: object + tests: + description: |- + Tests are strings used to identify slices of inbound snapshot traffic this + workload is targeting and maps directly to a snapshot's `InTraffic` field. + Snapshot ingress traffic can be split across multiple slices where each + slice contains part of the traffic. A key must only be specified once + across all workloads, but a workload may specify multiple keys. Pass '*' + to match all keys. + + + Test strings may only match part of the snapshot's `InTraffic` key if the + string matches exactly one key. For example, the test string + `foo.example.com` would match the `InTraffic` key of + my-service:foo.example.com:8080, as long as no other keys would match + `foo.example.com` + + + This field is optional in the spec to provide support for single-workload + and legacy replays, but must be specified for multi-workload replays in + order to provide deterministic replay configuration. + items: + type: string + type: array + type: object + type: array + required: + - snapshotID + - testConfigID + type: object + status: + default: + observedGeneration: -1 + description: TrafficReplayStatus defines the observed state of TrafficReplay + properties: + active: + description: Active indicates whether this traffic replay is currently + underway or not. + type: boolean + conditions: + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + finishedTime: + description: Information when the traffic replay has finished. + format: date-time + type: string + initializedTime: + description: Information when the test environment was successfully + prepared. + format: date-time + type: string + lastHeartbeatTime: + description: 'DEPRECATED: will not be set' + format: date-time + type: string + observedGeneration: + description: ObservedGeneration is the last observed generation. + format: int64 + type: integer + reconcileFailures: + description: |- + ReconcileFailures is the number of times the traffic replay controller + experienced an error during the reconciliation process. The traffic + replay will be deleted if too many errors occur. + format: int64 + type: integer + reportID: + description: The id of the traffic replay report created. + type: string + reportURL: + description: The url to the traffic replay report. + type: string + startedTime: + description: Information when the traffic replay has started. + format: date-time + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/charts/speedscale/speedscale-operator/2.2.467/templates/deployments.yaml b/charts/speedscale/speedscale-operator/2.2.467/templates/deployments.yaml new file mode 100644 index 0000000000..e5f3292579 --- /dev/null +++ b/charts/speedscale/speedscale-operator/2.2.467/templates/deployments.yaml @@ -0,0 +1,132 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + operator.speedscale.com/ignore: "true" + {{- if .Values.globalAnnotations }} +{{ toYaml .Values.globalAnnotations | indent 4}} + {{- end }} + labels: + app: speedscale-operator + controlplane.speedscale.com/component: operator + {{- if .Values.globalLabels }} +{{ toYaml .Values.globalLabels | indent 4}} + {{- end }} + name: speedscale-operator + namespace: {{ .Release.Namespace }} +spec: + replicas: 1 + selector: + matchLabels: + app: speedscale-operator + controlplane.speedscale.com/component: operator + strategy: + type: Recreate + template: + metadata: + annotations: + {{- if .Values.globalAnnotations }} +{{ toYaml .Values.globalAnnotations | indent 8}} + {{- end }} + labels: + app: speedscale-operator + controlplane.speedscale.com/component: operator + {{- if .Values.globalLabels }} +{{ toYaml .Values.globalLabels | indent 8}} + {{- end }} + spec: + containers: + - command: + - /operator + env: + - name: POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + envFrom: + - configMapRef: + name: speedscale-operator + # https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#container-v1-core + # When a key exists in multiple sources, the value associated with the last source will take precedence. + # Values defined by an Env with a duplicate key will take precedence. + - configMapRef: + name: speedscale-operator-override + optional: true + - secretRef: + name: '{{ ne .Values.apiKeySecret "" | ternary .Values.apiKeySecret "speedscale-apikey" }}' + optional: false + image: '{{ .Values.image.registry }}/operator:{{ .Values.image.tag }}' + imagePullPolicy: {{ .Values.image.pullPolicy }} + livenessProbe: + failureThreshold: 5 + httpGet: + path: /healthz + port: health-check + scheme: HTTP + initialDelaySeconds: 30 + periodSeconds: 30 + successThreshold: 1 + timeoutSeconds: 5 + name: operator + ports: + - containerPort: 443 + name: webhook-server + - containerPort: 8081 + name: health-check + readinessProbe: + failureThreshold: 10 + httpGet: + path: /readyz + port: health-check + scheme: HTTP + initialDelaySeconds: 5 + periodSeconds: 5 + successThreshold: 1 + timeoutSeconds: 5 + resources: {{- toYaml .Values.operator.resources | nindent 10 }} + securityContext: + allowPrivilegeEscalation: false + privileged: false + readOnlyRootFilesystem: true + runAsNonRoot: false + # Run as root to bind 443 https://github.com/kubernetes/kubernetes/issues/56374 + runAsUser: 0 + volumeMounts: + - mountPath: /tmp + name: tmp + - mountPath: /tmp/k8s-webhook-server/serving-certs + name: webhook-certs + readOnly: true + - mountPath: /etc/ssl/speedscale + name: speedscale-tls-out + readOnly: true + hostNetwork: {{ .Values.hostNetwork }} + securityContext: + runAsNonRoot: true + serviceAccountName: speedscale-operator + terminationGracePeriodSeconds: 10 + volumes: + - emptyDir: {} + name: tmp + - name: webhook-certs + secret: + secretName: speedscale-webhook-certs + - name: speedscale-tls-out + secret: + secretName: speedscale-certs + {{- if .Values.affinity }} + affinity: {{ toYaml .Values.affinity | nindent 8 }} + {{- end }} + {{- if .Values.tolerations }} + tolerations: {{ toYaml .Values.tolerations | nindent 8 }} + {{- end }} + {{- if .Values.nodeSelector }} + nodeSelector: {{ toYaml .Values.nodeSelector | nindent 8 }} + {{- end }} diff --git a/charts/speedscale/speedscale-operator/2.2.467/templates/hooks.yaml b/charts/speedscale/speedscale-operator/2.2.467/templates/hooks.yaml new file mode 100644 index 0000000000..3e8231f194 --- /dev/null +++ b/charts/speedscale/speedscale-operator/2.2.467/templates/hooks.yaml @@ -0,0 +1,73 @@ +--- +apiVersion: batch/v1 +kind: Job +metadata: + annotations: + helm.sh/hook: pre-install + helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded + helm.sh/hook-weight: "4" + {{- if .Values.globalAnnotations }} +{{ toYaml .Values.globalAnnotations | indent 4}} + {{- end }} + creationTimestamp: null + name: speedscale-operator-pre-install + namespace: {{ .Release.Namespace }} + labels: + {{- if .Values.globalLabels }} +{{ toYaml .Values.globalLabels | indent 4}} + {{- end }} +spec: + backoffLimit: 0 + ttlSecondsAfterFinished: 30 + template: + metadata: + annotations: + {{- if .Values.globalAnnotations }} +{{ toYaml .Values.globalAnnotations | indent 8}} + {{- end }} + creationTimestamp: null + labels: + {{- if .Values.globalLabels }} +{{ toYaml .Values.globalLabels | indent 8}} + {{- end }} + spec: + containers: + - args: + - |- + # ensure valid settings before the chart reports a successfull install + {{- if .Values.http_proxy }} + HTTP_PROXY={{ .Values.http_proxy | quote }} \ + {{- end }} + {{- if .Values.https_proxy }} + HTTPS_PROXY={{ .Values.https_proxy | quote }} \ + {{- end }} + {{- if .Values.no_proxy }} + NO_PROXY={{ .Values.no_proxy | quote }} \ + {{- end }} + speedctl init --overwrite --no-rcfile-update \ + --api-key $SPEEDSCALE_API_KEY \ + --app-url $SPEEDSCALE_APP_URL + + # in case we're in istio + curl -X POST http://127.0.0.1:15000/quitquitquit || true + command: + - sh + - -c + envFrom: + - secretRef: + name: '{{ ne .Values.apiKeySecret "" | ternary .Values.apiKeySecret "speedscale-apikey" }}' + optional: false + image: '{{ .Values.image.registry }}/speedscale-cli:{{ .Values.image.tag }}' + imagePullPolicy: {{ .Values.image.pullPolicy }} + name: speedscale-cli + resources: {} + restartPolicy: Never + {{- if .Values.affinity }} + affinity: {{ toYaml .Values.affinity | nindent 8 }} + {{- end }} + {{- if .Values.tolerations }} + tolerations: {{ toYaml .Values.tolerations | nindent 8 }} + {{- end }} + {{- if .Values.nodeSelector }} + nodeSelector: {{ toYaml .Values.nodeSelector | nindent 8 }} + {{- end }} diff --git a/charts/speedscale/speedscale-operator/2.2.467/templates/rbac.yaml b/charts/speedscale/speedscale-operator/2.2.467/templates/rbac.yaml new file mode 100644 index 0000000000..e1ea42d999 --- /dev/null +++ b/charts/speedscale/speedscale-operator/2.2.467/templates/rbac.yaml @@ -0,0 +1,244 @@ +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + name: speedscale-operator + {{- if .Values.globalAnnotations }} + annotations: {{ toYaml .Values.globalAnnotations | nindent 4 }} + {{- end }} +rules: +- apiGroups: + - apps + resources: + - deployments + - statefulsets + - daemonsets + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +- apiGroups: + - apps + resources: + - replicasets + verbs: + - delete + - deletecollection + - get + - list + - patch + - update + - watch +- apiGroups: + - batch + resources: + - jobs + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +- apiGroups: + - apiextensions.k8s.io + resources: + - customresourcedefinitions + verbs: + - get + - list +- apiGroups: + - admissionregistration.k8s.io + resources: + - mutatingwebhookconfigurations + - validatingwebhookconfigurations + verbs: + - get + - list +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterrolebindings + - clusterroles + verbs: + - get + - list +- apiGroups: + - "" + resources: + - namespaces + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - configmaps + - secrets + - pods + - services + - serviceaccounts + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +- apiGroups: + - "" + resources: + - pods/log + verbs: + - get + - list +- apiGroups: + - "" + resources: + - events + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - nodes + verbs: + - get + - list + - watch +- apiGroups: + - metrics.k8s.io + resources: + - pods + verbs: + - get + - list + - watch +- apiGroups: + - rbac.authorization.k8s.io + resources: + - rolebindings + - roles + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +- apiGroups: + - networking.istio.io + resources: + - envoyfilters + - sidecars + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +- apiGroups: + - security.istio.io + resources: + - peerauthentications + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +- apiGroups: + - speedscale.com + resources: + - trafficreplays + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +- apiGroups: + - speedscale.com + resources: + - trafficreplays/status + verbs: + - get + - update + - patch +- apiGroups: + - argoproj.io + resources: + - rollouts + verbs: + - get + - list + - patch + - update + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: speedscale-operator + {{- if .Values.globalAnnotations }} + annotations: {{ toYaml .Values.globalAnnotations | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: speedscale-operator +subjects: +- kind: ServiceAccount + name: speedscale-operator + namespace: {{ .Release.Namespace }} +--- +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + creationTimestamp: null + labels: + app: speedscale-operator + controlplane.speedscale.com/component: operator + name: speedscale-operator + namespace: {{ .Release.Namespace }} + {{- if .Values.globalAnnotations }} + annotations: {{ toYaml .Values.globalAnnotations | nindent 4 }} + {{- end }} diff --git a/charts/speedscale/speedscale-operator/2.2.467/templates/secrets.yaml b/charts/speedscale/speedscale-operator/2.2.467/templates/secrets.yaml new file mode 100644 index 0000000000..1fb6999e4c --- /dev/null +++ b/charts/speedscale/speedscale-operator/2.2.467/templates/secrets.yaml @@ -0,0 +1,18 @@ +--- +{{ if .Values.apiKey }} +apiVersion: v1 +kind: Secret +metadata: + name: speedscale-apikey + namespace: {{ .Release.Namespace }} + annotations: + helm.sh/hook: pre-install + helm.sh/hook-weight: "3" + {{- if .Values.globalAnnotations }} +{{ toYaml .Values.globalAnnotations | indent 4}} + {{- end }} +type: Opaque +data: + SPEEDSCALE_API_KEY: {{ .Values.apiKey | b64enc }} + SPEEDSCALE_APP_URL: {{ .Values.appUrl | b64enc }} +{{ end }} diff --git a/charts/speedscale/speedscale-operator/2.2.467/templates/services.yaml b/charts/speedscale/speedscale-operator/2.2.467/templates/services.yaml new file mode 100644 index 0000000000..f9da2c25c1 --- /dev/null +++ b/charts/speedscale/speedscale-operator/2.2.467/templates/services.yaml @@ -0,0 +1,22 @@ +--- +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + app: speedscale-operator + controlplane.speedscale.com/component: operator + name: speedscale-operator + namespace: {{ .Release.Namespace }} + {{- if .Values.globalAnnotations }} + annotations: {{ toYaml .Values.globalAnnotations | nindent 4 }} + {{- end }} +spec: + ports: + - port: 443 + protocol: TCP + selector: + app: speedscale-operator + controlplane.speedscale.com/component: operator +status: + loadBalancer: {} diff --git a/charts/speedscale/speedscale-operator/2.2.467/templates/tls.yaml b/charts/speedscale/speedscale-operator/2.2.467/templates/tls.yaml new file mode 100644 index 0000000000..4a24562884 --- /dev/null +++ b/charts/speedscale/speedscale-operator/2.2.467/templates/tls.yaml @@ -0,0 +1,183 @@ +{{- $crt := "" -}} +{{- $key := "" -}} +{{- $s := (lookup "v1" "Secret" .Release.Namespace "speedscale-certs") -}} +{{- if $s -}} +{{- $crt = index $s.data "tls.crt" | b64dec -}} +{{- $key = index $s.data "tls.key" | b64dec -}} +{{ else }} +{{- $cert := genCA "Speedscale" 3650 -}} +{{- $crt = $cert.Cert -}} +{{- $key = $cert.Key -}} +{{- end -}} +--- +apiVersion: batch/v1 +kind: Job +metadata: + annotations: + helm.sh/hook: pre-install + helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded + helm.sh/hook-weight: "5" + {{- if .Values.globalAnnotations }} +{{ toYaml .Values.globalAnnotations | indent 4}} + {{- end }} + creationTimestamp: null + name: speedscale-operator-create-jks + namespace: {{ .Release.Namespace }} + labels: + {{- if .Values.globalLabels }} +{{ toYaml .Values.globalLabels | indent 4}} + {{- end }} +spec: + backoffLimit: 0 + ttlSecondsAfterFinished: 30 + template: + metadata: + annotations: + {{- if .Values.globalAnnotations }} +{{ toYaml .Values.globalAnnotations | indent 8}} + {{- end }} + creationTimestamp: null + labels: + {{- if .Values.globalAnnotations }} +{{ toYaml .Values.globalAnnotations | indent 8}} + {{- end }} + spec: + containers: + - args: + - |- + keytool -keystore /usr/lib/jvm/jre/lib/security/cacerts -importcert -noprompt -trustcacerts -storepass changeit -alias speedscale -file /etc/ssl/speedscale/tls.crt + kubectl -n ${POD_NAMESPACE} delete secret speedscale-jks || true + kubectl -n ${POD_NAMESPACE} create secret generic speedscale-jks --from-file=cacerts.jks=/usr/lib/jvm/jre/lib/security/cacerts + + # in case we're in istio + curl -X POST http://127.0.0.1:15000/quitquitquit || true + command: + - sh + - -c + volumeMounts: + - mountPath: /etc/ssl/speedscale + name: speedscale-tls-out + readOnly: true + env: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + envFrom: + - secretRef: + name: '{{ ne .Values.apiKeySecret "" | ternary .Values.apiKeySecret "speedscale-apikey" }}' + optional: false + image: '{{ .Values.image.registry }}/amazoncorretto' + imagePullPolicy: {{ .Values.image.pullPolicy }} + name: create-jks + resources: {} + restartPolicy: Never + serviceAccountName: speedscale-operator-provisioning + volumes: + - name: speedscale-tls-out + secret: + secretName: speedscale-certs + {{- if .Values.affinity }} + affinity: {{ toYaml .Values.affinity | nindent 8 }} + {{- end }} + {{- if .Values.tolerations }} + tolerations: {{ toYaml .Values.tolerations | nindent 8 }} + {{- end }} + {{- if .Values.nodeSelector }} + nodeSelector: {{ toYaml .Values.nodeSelector | nindent 8 }} + {{- end }} +--- +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + annotations: + helm.sh/hook: pre-install + helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded + helm.sh/hook-weight: "1" + {{- if .Values.globalAnnotations }} +{{ toYaml .Values.globalAnnotations | indent 4}} + {{- end }} + creationTimestamp: null + labels: + app: speedscale-operator + controlplane.speedscale.com/component: operator + name: speedscale-operator-provisioning + namespace: {{ .Release.Namespace }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + annotations: + helm.sh/hook: pre-install + helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded + helm.sh/hook-weight: "2" + creationTimestamp: null + name: speedscale-operator-provisioning +rules: +- apiGroups: + - "" + resources: + - secrets + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +- apiGroups: + - admissionregistration.k8s.io + resources: + - mutatingwebhookconfigurations + - validatingwebhookconfigurations + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + annotations: + helm.sh/hook: pre-install + helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded + helm.sh/hook-weight: "3" + {{- if .Values.globalAnnotations }} +{{ toYaml .Values.globalAnnotations | indent 4}} + {{- end }} + creationTimestamp: null + name: speedscale-operator-provisioning +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: speedscale-operator-provisioning +subjects: +- kind: ServiceAccount + name: speedscale-operator-provisioning + namespace: {{ .Release.Namespace }} +--- +apiVersion: v1 +kind: Secret +metadata: + annotations: + helm.sh/hook: pre-install + helm.sh/hook-delete-policy: before-hook-creation + {{- if .Values.globalAnnotations }} +{{ toYaml .Values.globalAnnotations | indent 4}} + {{- end }} + creationTimestamp: null + name: speedscale-certs + namespace: {{ .Release.Namespace }} +type: kubernetes.io/tls +data: + tls.crt: {{ $crt | b64enc }} + tls.key: {{ $key | b64enc }} diff --git a/charts/speedscale/speedscale-operator/2.2.467/values.yaml b/charts/speedscale/speedscale-operator/2.2.467/values.yaml new file mode 100644 index 0000000000..36a88a59cc --- /dev/null +++ b/charts/speedscale/speedscale-operator/2.2.467/values.yaml @@ -0,0 +1,138 @@ +# An API key is required to connect to the Speedscale cloud. +# If you need a key email support@speedscale.com. +apiKey: "" + +# A secret name can be referenced instead of the api key itself. +# The secret must be of the format: +# +# type: Opaque +# data: +# SPEEDSCALE_API_KEY: +# SPEEDSCALE_APP_URL: +apiKeySecret: "" + +# Speedscale domain to use. +appUrl: "app.speedscale.com" + +# The name of your cluster. +clusterName: "my-cluster" + +# Speedscale components image settings. +image: + registry: gcr.io/speedscale + tag: v2.2.467 + pullPolicy: Always + +# Log level for Speedscale components. +logLevel: "info" + +# Namespaces to be watched by Speedscale Operator as a list of names. +namespaceSelector: [] + +# Instructs operator to deploy resources necessary to interact with your cluster from the Speedscale dashboard. +dashboardAccess: true + +# Filter Rule to apply to the Speedscale Forwarder +filterRule: "standard" + +# Data Loss Prevention settings. +dlp: + # Instructs operator to enable data loss prevention features + enabled: false + + # Configuration for data loss prevention + config: "standard" + +# If the operator pod/webhooks need to be on the host network. +# This is only needed if the control plane cannot connect directly to a pod +# for eg. if Calico is used as EKS's default networking +# https://docs.tigera.io/calico/3.25/getting-started/kubernetes/managed-public-cloud/eks#install-eks-with-calico-networking +hostNetwork: false + +# A set of annotations to be applied to all Speedscale related deployments, +# services, jobs, pods, etc. +# +# Example: +# annotation.first: value +# annotation.second: value +globalAnnotations: {} + +# A set of labels to be applied to all Speedscale related deployments, +# services, jobs, pods, etc. +# +# Example: +# label1: value +# label2: value +globalLabels: {} + +# A full affinity object as detailed: https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity +affinity: {} + +# The list of tolerations as detailed: https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/ +tolerations: [] + +# A nodeselector object as detailed: https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes/ +nodeSelector: {} + +# Deploy a demo app at startup. Set this to an empty string to not deploy. +# Valid values: ["java", ""] +deployDemo: "java" + +# Proxy connection settings if required by your network. These translate to standard proxy environment +# variables HTTP_PROXY, HTTPS_PROXY, and NO_PROXY +http_proxy: "" +https_proxy: "" +no_proxy: "" + +# control if sidecar init containers should run with privileged set +privilegedSidecars: false + +# control if the sidecar should enable/disable use of the smart dns lookup feature (requires NET_ADMIN) +disableSidecarSmartReverseDNS: false + +# Operator settings. These limits are recommended unless you have a cluster +# with a very large number of workloads (for eg. 10k+ deployments, replicasets, etc.). +operator: + resources: + limits: + cpu: 500m + memory: 512Mi + requests: + cpu: 100m + memory: 128Mi + # how long to wait for the SUT to become ready + test_prep_timeout: 10m + # timeout for deploying & upgrading control plane components + control_plane_timeout: 5m + + +# Default sidecar settings. Example: +# sidecar: +# resources: +# limits: +# cpu: 500m +# memory: 512Mi +# ephemeral-storage: 100Mi +# requests: +# cpu: 10m +# memory: 32Mi +# ephemeral-storage: 100Mi +# ignore_src_hosts: example.com, example.org +# ignore_src_ips: 8.8.8.8, 1.1.1.1 +# ignore_dst_hosts: example.com, example.org +# ignore_dst_ips: 8.8.8.8, 1.1.1.1 +# insert_init_first: false +# tls_out: false +# reinitialize_iptables: false +sidecar: {} + +# Forwarder settings +# forwarder: +# resources: +# limits: +# cpu: 500m +# memory: 500M +# requests: +# cpu: 300m +# memory: 250M +forwarder: {} diff --git a/index.yaml b/index.yaml index 22a70adf15..5788beaff8 100644 --- a/index.yaml +++ b/index.yaml @@ -4107,6 +4107,38 @@ entries: - assets/cerbos/cerbos-0.37.0.tgz version: 0.37.0 cf-runtime: + - annotations: + artifacthub.io/changes: | + - kind: security + description: "updating k8s-agent" + artifacthub.io/containsSecurityUpdates: "false" + catalog.cattle.io/certified: partner + catalog.cattle.io/display-name: Codefresh + catalog.cattle.io/kube-version: '>=1.18-0' + catalog.cattle.io/release-name: cf-runtime + apiVersion: v2 + created: "2024-09-26T00:53:44.946740062Z" + dependencies: + - name: cf-common + repository: file://./charts/cf-common + version: 0.16.0 + description: A Helm chart for Codefresh Runner + digest: 57c482a07bb89c453201cc05aa81b104027e2ee6406ad947cab2d35027ca6300 + home: https://codefresh.io/ + icon: file://assets/icons/cf-runtime.png + keywords: + - codefresh + - runner + kubeVersion: '>=1.18-0' + maintainers: + - name: codefresh + url: https://codefresh-io.github.io/ + name: cf-runtime + sources: + - https://github.com/codefresh-io/venona + urls: + - assets/codefresh/cf-runtime-6.4.1.tgz + version: 6.4.1 - annotations: artifacthub.io/changes: | - kind: added @@ -8709,6 +8741,33 @@ entries: - assets/dell/csi-powermax-2.7.0.tgz version: 2.7.0 csi-powerstore: + - annotations: + catalog.cattle.io/certified: partner + catalog.cattle.io/display-name: Dell CSI PowerStore + catalog.cattle.io/kube-version: '>= 1.24.0' + catalog.cattle.io/release-name: powerstore + apiVersion: v2 + appVersion: 2.11.1 + created: "2024-09-26T00:53:45.123333254Z" + description: 'PowerStore CSI (Container Storage Interface) driver Kubernetes integration. + This chart includes everything required to provision via CSI as well as a PowerStore + StorageClass. ' + digest: f90116c4990e3e51c9f9b8f550ee7109f97dde251cbfaf10aa854977613d4699 + home: https://github.com/dell/csi-powerstore + icon: file://assets/icons/csi-powerstore.png + keywords: + - csi + - storage + kubeVersion: '>= 1.24.0' + maintainers: + - name: DellEMC + name: csi-powerstore + sources: + - https://github.com/dell/csi-powerstore + type: application + urls: + - assets/dell/csi-powerstore-2.11.1.tgz + version: 2.11.1 - annotations: catalog.cattle.io/certified: partner catalog.cattle.io/display-name: Dell CSI PowerStore @@ -8871,6 +8930,32 @@ entries: - assets/dell/csi-powerstore-2.7.0.tgz version: 2.7.0 csi-unity: + - annotations: + catalog.cattle.io/certified: partner + catalog.cattle.io/display-name: Dell CSI Unity + catalog.cattle.io/kube-version: '>= 1.24.0' + catalog.cattle.io/release-name: unity + apiVersion: v2 + appVersion: 2.11.1 + created: "2024-09-26T00:53:45.12843868Z" + description: 'Unity XT CSI (Container Storage Interface) driver Kubernetes integration. + This chart includes everything required to provision via CSI as well as a Unity + XT StorageClass. ' + digest: 6396b3da9890c5504361e0e9b7058715e05fc787e876aa228dbeabf35a96e377 + icon: file://assets/icons/csi-unity.png + keywords: + - csi + - storage + kubeVersion: '>= 1.24.0' + maintainers: + - name: DellEMC + name: csi-unity + sources: + - https://github.com/dell/csi-unity + type: application + urls: + - assets/dell/csi-unity-2.11.1.tgz + version: 2.11.1 - annotations: catalog.cattle.io/certified: partner catalog.cattle.io/display-name: Dell CSI Unity @@ -10283,6 +10368,35 @@ entries: - assets/dynatrace/dynatrace-operator-0.12.0.tgz version: 0.12.0 external-secrets: + - annotations: + catalog.cattle.io/certified: partner + catalog.cattle.io/display-name: External Secrets Operator + catalog.cattle.io/kube-version: '>= 1.19.0-0' + catalog.cattle.io/release-name: external-secrets + apiVersion: v2 + appVersion: v0.10.4 + created: "2024-09-26T00:53:45.186382552Z" + dependencies: + - condition: bitwarden-sdk-server.enabled + name: bitwarden-sdk-server + repository: file://./charts/bitwarden-sdk-server + version: v0.3.1 + description: External secret management for Kubernetes + digest: 4ac941252c1cb351e019c1c5743c130acd932d452136192f829f0f6493490c2e + home: https://github.com/external-secrets/external-secrets + icon: file://assets/icons/external-secrets.png + keywords: + - kubernetes-external-secrets + - secrets + kubeVersion: '>= 1.19.0-0' + maintainers: + - email: kellinmcavoy@gmail.com + name: mcavoyk + name: external-secrets + type: application + urls: + - assets/external-secrets/external-secrets-0.10.4.tgz + version: 0.10.4 - annotations: catalog.cattle.io/certified: partner catalog.cattle.io/display-name: External Secrets Operator @@ -36461,6 +36575,37 @@ entries: - assets/btp/sextant-2.2.21.tgz version: 2.2.21 speedscale-operator: + - annotations: + catalog.cattle.io/certified: partner + catalog.cattle.io/display-name: Speedscale Operator + catalog.cattle.io/kube-version: '>= 1.17.0-0' + catalog.cattle.io/release-name: speedscale-operator + apiVersion: v1 + appVersion: 2.2.467 + created: "2024-09-26T00:53:49.047108513Z" + description: Stress test your APIs with real world scenarios. Collect and replay + traffic without scripting. + digest: 9df1d2c831416f1fea8bdf90d72bed961635eabc919ab93a903370702431ae26 + home: https://speedscale.com + icon: file://assets/icons/speedscale-operator.png + keywords: + - speedscale + - test + - testing + - regression + - reliability + - load + - replay + - network + - traffic + kubeVersion: '>= 1.17.0-0' + maintainers: + - email: support@speedscale.com + name: Speedscale Support + name: speedscale-operator + urls: + - assets/speedscale/speedscale-operator-2.2.467.tgz + version: 2.2.467 - annotations: catalog.cattle.io/certified: partner catalog.cattle.io/display-name: Speedscale Operator @@ -43157,4 +43302,4 @@ entries: urls: - assets/netfoundry/ziti-host-1.5.1.tgz version: 1.5.1 -generated: "2024-09-25T00:55:18.712681434Z" +generated: "2024-09-26T00:53:44.532035678Z"